screen system
authorJohn Tsiombikas <nuclear@mutantstargoat.com>
Sun, 21 Aug 2016 05:01:49 +0000 (08:01 +0300)
committerJohn Tsiombikas <nuclear@mutantstargoat.com>
Sun, 21 Aug 2016 05:01:49 +0000 (08:01 +0300)
.clang_complete [new file with mode: 0644]
src/conscr.c [new file with mode: 0644]
src/demo.h [new file with mode: 0644]
src/main.c
src/screen.c [new file with mode: 0644]
src/screen.h [new file with mode: 0644]
src/tunnel.c
src/tunnel.h [deleted file]

diff --git a/.clang_complete b/.clang_complete
new file mode 100644 (file)
index 0000000..42d3a7d
--- /dev/null
@@ -0,0 +1 @@
+-x c
diff --git a/src/conscr.c b/src/conscr.c
new file mode 100644 (file)
index 0000000..4c56fb0
--- /dev/null
@@ -0,0 +1,86 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "screen.h"
+#include "demo.h"
+
+static int init(void);
+static void destroy(void);
+static void start(long trans_time);
+static void stop(long trans_time);
+static void draw(void);
+
+static struct screen scr = {
+       "console",
+       init,
+       destroy,
+       start,
+       stop,
+       draw
+};
+
+static void *saved_fb;
+static int fbsize;
+static long trans_start, trans_dur;
+
+struct screen *console_screen(void)
+{
+       return &scr;
+}
+
+static int init(void)
+{
+       fbsize = fb_width * fb_height * fb_depth / 8;
+
+       if(!(saved_fb = malloc(fbsize))) {
+               perror("failed to allocate memory");
+               return -1;
+       }
+       memcpy(saved_fb, fb_pixels, fbsize);
+       return 0;
+}
+
+static void destroy(void)
+{
+       memcpy(fb_pixels, saved_fb, fbsize);
+       free(saved_fb);
+}
+
+static void start(long trans_time)
+{
+}
+
+static void stop(long trans_time)
+{
+       trans_start = time_msec;
+       trans_dur = trans_time;
+}
+
+static void draw(void)
+{
+       int i, pixsz = fb_depth / 8;
+       long elapsed, offs, rem;
+       unsigned char *dptr = fb_pixels;
+       unsigned char *sptr = saved_fb;
+
+       if(!trans_start) {
+               return;
+       }
+       printf("console draw\n");
+
+       elapsed = time_msec - trans_start;
+       offs = fb_width * elapsed / trans_dur;
+       rem = fb_width - offs;
+
+       for(i=0; i<fb_height; i++) {
+               if(offs > 0) {
+                       memset(dptr, 0, offs * pixsz);
+               }
+               if(rem > 0) {
+                       memcpy(dptr + offs * pixsz, sptr, rem * pixsz);
+               }
+
+               dptr += fb_width * pixsz;
+               sptr += fb_width * pixsz;
+       }
+}
diff --git a/src/demo.h b/src/demo.h
new file mode 100644 (file)
index 0000000..6e10b78
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef DEMO_H_
+#define DEMO_H_
+
+void *fb_pixels;
+int fb_width, fb_height;
+int fb_depth;
+
+long time_msec;
+
+#endif /* DEMO_H_ */
index f0588c0..1cd4950 100644 (file)
@@ -3,17 +3,16 @@
 #include <string.h>
 #include "fbgfx.h"
 #include "fbevents.h"
-#include "tunnel.h"
 #include "timer.h"
-
-unsigned long start_msec, time_msec, num_frames;
+#include "screen.h"
+#include "screen.h"
+#include "demo.h"
 
 static void keyboard(int key, int pressed, void *cls);
 static void mouse(int bn, int pressed, int x, int y, void *cls);
 static void motion(int x, int y, void *cls);
 
-static void *vmem;
-static int xsz, ysz, depth;
+static long start_msec, num_frames;
 
 static int quit;
 
@@ -23,20 +22,20 @@ int main(void)
        int i, trybpp[] = {32, 24, 16, 0};
 
        fbgfx_save_video_mode();
-       fbgfx_get_video_mode(&xsz, &ysz, &depth);
+       fbgfx_get_video_mode(&fb_width, &fb_height, &fb_depth);
 
        for(i=0; trybpp[i]; i++) {
-               if(!(vmem = fbgfx_set_video_mode(xsz, ysz, trybpp[i]))) {
+               if(!(fb_pixels = fbgfx_set_video_mode(fb_width, fb_height, trybpp[i]))) {
                        continue;
                }
-               fbgfx_get_video_mode(&xsz, &ysz, &depth);
-               if(depth == trybpp[i]) {
+               fbgfx_get_video_mode(&fb_width, &fb_height, &fb_depth);
+               if(fb_depth == trybpp[i]) {
                        break;
                }
-               fprintf(stderr, "failed to set color depth: %dbpp\n", trybpp[i]);
+               fprintf(stderr, "failed to set color fb_depth: %dbpp\n", trybpp[i]);
        }
        if(trybpp[i] == 0) {
-               fprintf(stderr, "no usable color depths found\n");
+               fprintf(stderr, "no usable color fb_depths found\n");
                goto end;
        }
 
@@ -47,9 +46,11 @@ int main(void)
        fbev_mbutton(mouse, 0);
        fbev_mmotion(motion, 0);
 
-       if(init_tunnel(xsz, ysz, depth) == -1) {
+       if(scr_init() == -1) {
                goto end;
        }
+       scr_change(scr_lookup("console"), 0);
+       scr_change(scr_lookup("tunnel"), 2000);
 
        start_msec = get_time_msec();
        for(;;) {
@@ -58,13 +59,14 @@ int main(void)
 
                time_msec = get_time_msec() - start_msec;
 
-               draw_tunnel(vmem);
+               scr_update();
+               scr_draw();
                ++num_frames;
        }
 
        time_msec = get_time_msec() - start_msec;
 end:
-       destroy_tunnel();
+       scr_shutdown();
        fbev_shutdown();
        fbgfx_restore_video_mode();
        if(num_frames && time_msec) {
diff --git a/src/screen.c b/src/screen.c
new file mode 100644 (file)
index 0000000..1f1dfbe
--- /dev/null
@@ -0,0 +1,85 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "screen.h"
+#include "demo.h"
+
+struct screen *console_screen(void);
+struct screen *tunnel_screen(void);
+
+#define NUM_SCR        2
+static struct screen *scr[NUM_SCR];
+
+static struct screen *cur, *prev, *next;
+static long trans_start, trans_dur;
+
+int scr_init(void)
+{
+       int i;
+
+       if(!(scr[0] = console_screen())) {
+               return -1;
+       }
+       if(!(scr[1] = tunnel_screen())) {
+               return -1;
+       }
+
+       for(i=0; i<NUM_SCR; i++) {
+               if(scr[i]->init() == -1) {
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+void scr_shutdown(void)
+{
+       int i;
+       for(i=0; i<NUM_SCR; i++) {
+               scr[i]->shutdown();
+       }
+}
+
+void scr_update(void)
+{
+       if(prev) {      /* we're in the middle of a transition */
+               long interval = time_msec - trans_start;
+               if(interval >= trans_dur) {
+                       prev = 0;
+                       cur = next;
+                       next = 0;
+               }
+       }
+}
+
+void scr_draw(void)
+{
+       if(cur) cur->draw();
+}
+
+struct screen *scr_lookup(const char *name)
+{
+       int i;
+       for(i=0; i<NUM_SCR; i++) {
+               if(strcmp(scr[i]->name, name) == 0) {
+                       return scr[i];
+               }
+       }
+       return 0;
+}
+
+int scr_change(struct screen *s, long trans_time)
+{
+       if(s == cur) return 0;
+
+       if(trans_time && cur) {
+               trans_dur = trans_time / 2;     /* half for each part transition out then in */
+               trans_start = time_msec;
+
+               prev = cur;
+               next = s;
+       } else {
+               cur = s;
+       }
+       return 0;
+}
diff --git a/src/screen.h b/src/screen.h
new file mode 100644 (file)
index 0000000..9a449e8
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef SCREEN_H_
+#define SCREEN_H_
+
+struct screen {
+       char *name;
+
+       int (*init)(void);
+       void (*shutdown)(void);
+
+       void (*start)(long trans_time);
+       void (*stop)(long trans_time);
+
+       void (*draw)(void);
+};
+
+int scr_init(void);
+void scr_shutdown(void);
+
+void scr_update(void);
+void scr_draw(void);
+
+struct screen *scr_lookup(const char *name);
+int scr_change(struct screen *s, long trans_time);
+
+#endif /* SCREEN_H_ */
index c6504ce..4707d81 100644 (file)
@@ -4,7 +4,8 @@
 #include <assert.h>
 #include <imago2.h>
 #include "tpool.h"
-#include "tunnel.h"
+#include "demo.h"
+#include "screen.h"
 
 #define TEX_FNAME      "data/grid.png"
 #define TEX_USCALE     4
 #define USCALE 2
 #define VSCALE 1
 
-extern unsigned long time_msec;
+static int init(void);
+static void destroy(void);
+static void start(long trans_time);
+static void stop(long trans_time);
+static void draw(void);
 
 static void (*draw_tunnel_range)(void*, int, int);
 
@@ -22,6 +27,15 @@ static void draw_tunnel_range32(void *pixels, int starty, int num_lines);
 static int count_bits(unsigned int x);
 static int count_zeros(unsigned int x);
 
+static struct screen scr = {
+       "tunnel",
+       init,
+       destroy,
+       start,
+       stop,
+       draw
+};
+
 static int xsz, ysz, vxsz, vysz;
 static unsigned int *tunnel_map;
 static unsigned char *tunnel_fog;
@@ -34,14 +48,20 @@ static unsigned int tex_xmask, tex_ymask;
 static struct thread_pool *tpool;
 
 
-int init_tunnel(int x, int y, int bpp)
+struct screen *tunnel_screen(void)
+{
+       return &scr;
+}
+
+
+static int init(void)
 {
        int i, j, n;
        unsigned int *tmap;
        unsigned char *fog;
-       float aspect = (float)x / (float)y;
+       float aspect = (float)fb_width / (float)fb_height;
 
-       switch(bpp) {
+       switch(fb_depth) {
        case 16:
                draw_tunnel_range = draw_tunnel_range16;
                break;
@@ -49,12 +69,12 @@ int init_tunnel(int x, int y, int bpp)
                draw_tunnel_range = draw_tunnel_range32;
                break;
        default:
-               fprintf(stderr, "unsupported color depth: %d\n", bpp);
+               fprintf(stderr, "unsupported color depth: %d\n", fb_depth);
                return -1;
        }
 
-       xsz = x;
-       ysz = y;
+       xsz = fb_width;
+       ysz = fb_height;
        vxsz = xsz / USCALE;
        vysz = ysz / VSCALE;
 
@@ -117,13 +137,21 @@ int init_tunnel(int x, int y, int bpp)
        return 0;
 }
 
-void destroy_tunnel(void)
+static void destroy(void)
 {
        tpool_destroy(tpool);
        free(tunnel_map);
        free(tunnel_fog);
 }
 
+static void start(long trans_time)
+{
+}
+
+static void stop(long trans_time)
+{
+}
+
 #define NUM_WORK_ITEMS 32
 
 static struct work {
@@ -137,11 +165,11 @@ static void work_func(void *cls)
        draw_tunnel_range(w->pixels, w->starty, w->num_lines);
 }
 
-void draw_tunnel(void *pixels)
+static void draw(void)
 {
        int i, num_lines = vysz / NUM_WORK_ITEMS;
        for(i=0; i<NUM_WORK_ITEMS; i++) {
-               work[i].pixels = pixels;
+               work[i].pixels = fb_pixels;
                work[i].starty = i * num_lines;
                work[i].num_lines = num_lines;
 
diff --git a/src/tunnel.h b/src/tunnel.h
deleted file mode 100644 (file)
index 05a9864..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef TUNNEL_H_
-#define TUNNEL_H_
-
-int init_tunnel(int x, int y, int bpp);
-void destroy_tunnel(void);
-void draw_tunnel(void *pixels);
-
-#endif /* TUNNEL_H_ */