]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/jdb_tetris.cpp
Inital import
[l4.git] / kernel / fiasco / src / jdb / jdb_tetris.cpp
1 IMPLEMENTATION:
2
3 #include <cstdio>
4 #include <cstdlib>
5 #include "simpleio.h"
6
7 #include "jdb.h"
8 #include "jdb_module.h"
9 #include "static_init.h"
10 #include "types.h"
11 #include "cpu.h"
12 #include "globals.h"
13 #include "kernel_console.h"
14 #include "keycodes.h"
15
16 static int lines, score, current_pos, mode, slice,
17            *current_tile, *next_tile, grid[264], next[48];
18
19 static int tiles[] = {  9,      9,      -13,    -12,    1,      4,
20                         10,     10,     -11,    -12,    -1,     4,
21                         11,     13,     -1,     1,      12,     6,
22                         3,      3,      -13,    -12,    -1,     2,
23                         14,     16,     -1,     11,     1,      5,
24                         17,     19,     -1,     13,     1,      5,
25                         20,     20,     -1,     1,      2,      1,
26                         23,     21,     -12,    11,     13,     3,
27                         8,      8,      11,     13,     24,     1,
28                         0,      0,      -12,    -1,     11,     4,
29                         1,      1,      -12,    1,      13,     4,
30                         12,     2,      -12,    1,      12,     6,
31                         13,     11,     -12,    -1,     1,      6,
32                         2,      12,     -12,    -1,     12,     6,
33                         15,     4,      -12,    12,     13,     5,
34                         16,     14,     -11,    -1,     1,      5,
35                         4,      15,     -13,    -12,    12,     5,
36                         18,     5,      -11,    -12,    12,     5,
37                         19,     17,     -13,    1,      -1,     5,
38                         5,      18,     -12,    12,     11,     5,
39                         6,      6,      -12,    12,     24,     1,
40                         7,      22,     -13,    1,      11,     3,
41                         21,     23,     -13,    -11,    12,     3,
42                         22,     7,      -11,    -1,     13,     3 };
43
44 static const char *modes[] = { "", "Fiasco Mode", "Lars Mode" };
45 static long unsigned int randseed;
46
47 IMPLEMENTATION [ux]:
48
49 static unsigned slice_to_timeout(unsigned slice)
50 {
51   slice /= 50;
52   return slice < 2 ? 2 : slice;
53 }
54
55 static void show_grid()
56 {
57   int i, j;
58
59   printf ("\033[H");
60
61   for (i = j = 0; i < 264; i++)
62     {
63       if (grid[i])
64         printf ("\033[m\033[1;4%d;30m  \033[40m", grid[i]);
65       else
66         putstr ("  ");
67
68       if (i % 12 == 11)
69         {
70           for (; j <= i && j < 48; j++)
71             if (next[j])
72               printf ("\033[m\033[1;4%d;30m  \033[40m", next[j]);
73             else
74               putstr ("\033[m\033[30m  \033[m");
75
76           putchar ('\n');
77         }
78     }  
79
80   printf ("\033[mLines: %d   Score: %d   %s\033[K", lines, score, modes[mode]);
81 }
82
83 IMPLEMENTATION [!ux]:
84
85 static unsigned slice_to_timeout(unsigned slice)
86 {
87   return slice;
88 }
89
90 static void show_grid()
91 {
92   int i, j;
93
94   printf ("\033[H");
95
96   for (i = j = 0; i < 264; i++)
97     {
98       if (grid[i])
99         printf ("\033[1;3%dm\333\333", grid[i]);
100       else
101         putstr ("  ");
102
103       if (i % 12 == 11)
104         {
105           for (; j <= i && j < 48; j++)
106             if (next[j])
107               printf ("\033[1;3%dm\333\333", next[j]);
108             else
109               putstr ("  ");
110
111           putchar ('\n');
112         }
113     }  
114
115   printf ("Lines: %d   Score: %d   %s\033[K", lines, score, modes[mode]);
116 }
117
118 IMPLEMENTATION:
119
120 static int getchar_timeout()
121 {
122   int c;
123   static unsigned to = slice;
124
125   to = slice_to_timeout(to);
126   while (--to)
127     {
128       if ((c = Kconsole::console()->getchar (false)) != -1)
129         return c;
130
131       if (Config::getchar_does_hlt && Config::getchar_does_hlt_works_ok)
132         Proc::halt();
133       else
134         Cpu::cpus.cpu(0).busy_wait_ns(1000000ULL);
135     }
136
137   to = slice;
138
139   return -1;
140 }
141
142 static void add_score(int value)
143 {
144   if ((score + value) / 1000 != score / 1000)
145     slice--;
146
147   if (slice < 0)
148       slice = 0;
149
150   score += value;
151 }
152
153 static long unsigned int myrand() 
154 {
155   randseed = (randseed * 13561+14000) % 150001;
156   return randseed;
157 }
158
159 static int *new_tile()
160 {
161   return tiles + myrand() % (7 + mode) * 6;
162 }
163
164 static int try_move (int pos, int *tile)
165 {
166   if (grid[pos] + grid[pos+tile[2]] + grid[pos+tile[3]] + grid[pos+tile[4]])
167     return 0;
168
169   current_tile = tile;
170   current_pos  = pos;
171
172   return 1;
173 }
174  
175 static void set_grid (int color)
176 {
177   grid[current_pos] =
178   grid[current_pos+current_tile[2]] =
179   grid[current_pos+current_tile[3]] =
180   grid[current_pos+current_tile[4]] = color;
181 }
182
183 static void set_next (int color)
184 {
185   next[17] =
186   next[17+next_tile[2]] =
187   next[17+next_tile[3]] =
188   next[17+next_tile[4]] = color;
189 }
190
191 void show_tile (void)
192 {
193   set_grid(current_tile[5]);
194   set_next(next_tile[5]);   
195
196   show_grid();
197
198   set_grid(0);
199   set_next(0);
200 }
201
202 /**
203  * Jdb-tetris module
204  *
205  * This module makes fun.
206  */
207 class Jdb_tetris_m 
208   : public Jdb_module
209 {
210 public:
211   Jdb_tetris_m() FIASCO_INIT;
212 };
213
214 static Jdb_tetris_m jdb_tetris_m INIT_PRIORITY(JDB_MODULE_INIT_PRIO);
215
216 IMPLEMENT
217 Jdb_tetris_m::Jdb_tetris_m()
218   : Jdb_module("MISC")
219 {}
220
221 PUBLIC
222 Jdb_module::Action_code
223 Jdb_tetris_m::action( int, void *&, char const *&, int & )
224 {
225   int i, j, k, c;
226
227   lines = score = c = 0;
228   slice = 300;
229   randseed= Cpu::rdtsc() & 0xffffffff;
230
231   puts ("\nDisabling output of serial console -- quit Tetris with 'q'!");
232   Kconsole::console()->change_state(Console::UART, 0, ~Console::OUTENABLED, 0);
233
234   printf ("\033[H\033[J");
235
236   // Setup grid borders
237   for (i = 0; i < 264; i++)
238     grid[i] = (i % 12 == 0 || i % 12 == 11 || i > 251) ? 7 : 0;
239
240   try_move (17, new_tile());
241   next_tile = new_tile();
242
243   while (1)
244     {      
245       if (c < 0)
246         {
247           if (!try_move (current_pos + 12, current_tile))
248             {
249               set_grid(current_tile[5]);
250
251               for (i = k = 0; i < 252; i += 12)
252                 for (j = i; grid[++j];)
253                   if (j - i == 10) {   
254                     while (j > i) grid[j--] = 0;            show_grid();
255                     while (--j) grid[j + 12] = grid[j];     show_grid();
256                     k++;
257                   }         
258
259               lines += k;
260               add_score (k ? (1 << k) * 10 : 1);
261
262               if (!try_move (17, next_tile))
263                 break;
264
265               next_tile = new_tile();
266             }
267         }  
268
269       // Move left
270       else if (c == KEY_CURSOR_LEFT)
271         try_move (current_pos - 1, current_tile);
272
273       // Move right
274       else if (c == KEY_CURSOR_RIGHT)
275         try_move (current_pos + 1, current_tile);
276
277       // Drop tile
278       else if (c == ' ')
279         while (try_move (current_pos + 12, current_tile))
280           {
281             show_tile();
282             add_score(3);
283           }
284         
285       // Left-turn tile
286       else if (c == KEY_CURSOR_DOWN)
287         try_move (current_pos, tiles + 6 ** current_tile);
288
289       // Right-turn tile
290       else if (c == KEY_CURSOR_UP)
291         try_move (current_pos, tiles + 6 ** (current_tile+1));
292
293       // Quit
294       else if (c == 'q' || c == KEY_ESC)
295         break;
296
297       else if (c == 'm')
298         if (++mode == 3)
299           mode = 0;
300
301       show_tile();
302
303       c = getchar_timeout();
304     }
305
306   Kconsole::console()->change_state(Console::UART, 0, ~0U, Console::OUTENABLED);
307   printf ("\033[0m");
308
309   return NOTHING;
310 }
311
312 PUBLIC
313 int
314 Jdb_tetris_m::num_cmds() const
315
316   return 1;
317 }
318
319 PUBLIC
320 Jdb_module::Cmd const *
321 Jdb_tetris_m::cmds() const
322 {
323   static Cmd cs[] =
324     { 
325         { 0, "X", "X", "",
326            "X\tPlay Tetris (cursor keys = left/right/rotate;\n"
327            "\t[space] = drop; q = quit)", 0 },
328     };
329
330   return cs;
331 }