world's saddest console
[dosdemo] / src / screen.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 #include "screen.h"
6 #include "demo.h"
7
8 #define DBG_SCRCHG \
9         do { \
10                 dbg_curscr_name = cur->name ? cur->name : "<unknown>"; \
11                 dbg_curscr_name_len = strlen(dbg_curscr_name); \
12                 dbg_curscr_name_pos = 320 - dbg_curscr_name_len * 9; \
13         } while(0)
14
15 struct screen *tunnel_screen(void);
16 struct screen *fract_screen(void);
17 struct screen *grise_screen(void);
18 struct screen *polytest_screen(void);
19 struct screen *plasma_screen(void);
20 struct screen *bump_screen(void);
21 struct screen *thunder_screen(void);
22 struct screen *metaballs_screen(void);
23 struct screen *greets_screen(void);
24 struct screen *infcubes_screen(void);
25 struct screen *hairball_screen(void);
26
27 #define NUM_SCR 32
28 static struct screen *scr[NUM_SCR];
29 static int num_screens;
30
31 static struct screen *cur, *prev, *next;
32 static long trans_start, trans_dur;
33
34 int scr_init(void)
35 {
36         int i, idx = 0;
37
38         if(!(scr[idx++] = tunnel_screen())) {
39                 return -1;
40         }
41         if(!(scr[idx++] = fract_screen())) {
42                 return -1;
43         }
44         if (!(scr[idx++] = grise_screen())) {
45                 return -1;
46         }
47         if(!(scr[idx++] = polytest_screen())) {
48                 return -1;
49         }
50         if (!(scr[idx++] = plasma_screen())) {
51                 return -1;
52         }
53         if (!(scr[idx++] = bump_screen())) {
54                 return -1;
55         }
56         if (!(scr[idx++] = thunder_screen())) {
57                 return -1;
58         }
59         if(!(scr[idx++] = metaballs_screen())) {
60                 return -1;
61         }
62         if(!(scr[idx++] = greets_screen())) {
63                 return -1;
64         }
65         if(!(scr[idx++] = infcubes_screen())) {
66                 return -1;
67         }
68         if(!(scr[idx++] = hairball_screen())) {
69                 return -1;
70         }
71         num_screens = idx;
72
73         assert(num_screens <= NUM_SCR);
74
75         for(i=0; i<num_screens; i++) {
76                 if(scr[i]->init() == -1) {
77                         return -1;
78                 }
79         }
80         return 0;
81 }
82
83 void scr_shutdown(void)
84 {
85         int i;
86         for(i=0; i<num_screens; i++) {
87                 scr[i]->shutdown();
88         }
89 }
90
91 void scr_update(void)
92 {
93         if(prev) {  /* we're in the middle of a transition */
94                 long interval = time_msec - trans_start;
95                 if(interval >= trans_dur) {
96                         if(next->start) {
97                                 next->start(trans_dur);
98                         }
99                         prev = 0;
100                         cur = next;
101                         next = 0;
102
103                         DBG_SCRCHG;
104                 }
105         }
106 }
107
108
109 void scr_draw(void)
110 {
111         if(cur) {
112                 cur->draw();
113         }
114 }
115
116 void scr_keypress(int key)
117 {
118         if(cur && cur->keypress) {
119                 cur->keypress(key);
120         }
121 }
122
123 struct screen *scr_lookup(const char *name)
124 {
125         int i;
126         for(i=0; i<num_screens; i++) {
127                 if(strcmp(scr[i]->name, name) == 0) {
128                         return scr[i];
129                 }
130         }
131         return 0;
132 }
133
134 struct screen *scr_screen(int idx)
135 {
136         return scr[idx];
137 }
138
139 int scr_num_screens(void)
140 {
141         return num_screens;
142 }
143
144 int scr_change(struct screen *s, long trans_time)
145 {
146         if(!s) return -1;
147         if(s == cur) return 0;
148
149         if(trans_time) {
150                 trans_dur = trans_time / 2; /* half for each part transition out then in */
151                 trans_start = time_msec;
152         } else {
153                 trans_dur = 0;
154         }
155
156         if(cur && cur->stop) {
157                 cur->stop(trans_dur);
158                 prev = cur;
159                 next = s;
160         } else {
161                 if(s->start) {
162                         s->start(trans_dur);
163                 }
164
165                 cur = s;
166                 prev = 0;
167
168                 DBG_SCRCHG;
169         }
170         return 0;
171 }