]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/jdb_tetris.cpp
c23009bc4da55cc30c2c6f978b4cf1e83247d6e8
[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_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                     {
255                       while (j > i)
256                         grid[j--] = 0;
257                       show_grid();
258                       while (--j)
259                         grid[j + 12] = grid[j];
260                       show_grid();
261                       k++;
262                     }
263
264               lines += k;
265               add_score(k ? (1 << k) * 10 : 1);
266
267               if (!try_move(17, next_tile))
268                 break;
269
270               next_tile = new_tile();
271             }
272         }
273
274       // Move left
275       else if (c == KEY_CURSOR_LEFT)
276         try_move(current_pos - 1, current_tile);
277
278       // Move right
279       else if (c == KEY_CURSOR_RIGHT)
280         try_move(current_pos + 1, current_tile);
281
282       // Drop tile
283       else if (c == ' ')
284         while (try_move(current_pos + 12, current_tile))
285           {
286             show_tile();
287             add_score(3);
288           }
289
290       // Left-turn tile
291       else if (c == KEY_CURSOR_DOWN)
292         try_move(current_pos, tiles + 6 ** current_tile);
293
294       // Right-turn tile
295       else if (c == KEY_CURSOR_UP)
296         try_move(current_pos, tiles + 6 ** (current_tile + 1));
297
298       // Quit
299       else if (c == 'q' || c == KEY_ESC)
300         break;
301
302       else if (c == 'm')
303         if (++mode == 3)
304           mode = 0;
305
306       show_tile();
307
308       c = getchar_timeout();
309     }
310
311   Kconsole::console()->change_state(Console::UART, 0, ~0U, Console::OUTENABLED);
312   printf("\033[0m");
313
314   return NOTHING;
315 }
316
317 PUBLIC
318 int
319 Jdb_tetris_m::num_cmds() const
320 {
321   return 1;
322 }
323
324 PUBLIC
325 Jdb_module::Cmd const *
326 Jdb_tetris_m::cmds() const
327 {
328   static Cmd cs[] =
329     {
330         { 0, "X", "X", "",
331            "X\tPlay Tetris (cursor keys = left/right/rotate;\n"
332            "\t[space] = drop; q = quit)", 0 },
333     };
334
335   return cs;
336 }