~ubuntu-branches/ubuntu/precise/typespeed/precise

« back to all changes in this revision

Viewing changes to src/menu.c

  • Committer: Bazaar Package Importer
  • Author(s): Dafydd Harries
  • Date: 2007-12-07 05:14:13 UTC
  • mto: (4.1.2 sid)
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20071207051413-x6wtxujyiabvyuwu
Tags: upstream-0.6.4
ImportĀ upstreamĀ versionĀ 0.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  typespeed - measures your typing speed
 
3
 *  Copyright (C) 1999-2003   Jani Ollikainen  <bestis@iki.fi>
 
4
 *                          & Jaakko Manelius  <jman@iki.fi>
 
5
 *  Copyright (C) 2006-2007   Tobias Stoeckmann  <tobias@bugol.de>
 
6
 *
 
7
 *  This program is free software; you can redistribute it and/or modify
 
8
 *  it under the terms of the GNU General Public License as published by
 
9
 *  the Free Software Foundation; either version 2 of the License, or
 
10
 *  (at your option) any later version.
 
11
 *
 
12
 *  This program is distributed in the hope that it will be useful,
 
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 *  GNU General Public License for more details.
 
16
 *
 
17
 *  You should have received a copy of the GNU General Public License
 
18
 *  along with this program; if not, write to the Free Software
 
19
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
20
 */
 
21
 
 
22
/*
 
23
 * menu.c - menu & misc drawing functions
 
24
 */
 
25
 
 
26
#ifdef HAVE_CONFIG_H
 
27
        #include "config.h"
 
28
#endif /* HAVE_CONFIG_H */
 
29
 
 
30
#ifdef HAVE_SYS_PARAM_H
 
31
        #include <sys/param.h>
 
32
#endif /* HAVE_SYS_PARAM_H */
 
33
 
 
34
#include <curses.h>
 
35
#include <ctype.h>
 
36
#include <errno.h>
 
37
 
 
38
#ifdef HAVE_STDLIB_H
 
39
        #include <stdlib.h>
 
40
#endif /* HAVE_STDLIB_H */
 
41
 
 
42
#ifdef HAVE_STRING_H
 
43
        #include <string.h>
 
44
#endif /* HAVE_STRING_H */
 
45
 
 
46
#include "gettext.h"
 
47
#include "typespeed.h"
 
48
 
 
49
#define _(string)       gettext(string)
 
50
 
 
51
extern int              chooseruleset(void);
 
52
extern int              choosewordfile(int);
 
53
extern void             closenetwork(void);
 
54
extern unsigned long    cstrl(char *);
 
55
extern void             xerrx(int, const char *, ...);
 
56
extern int              initnetwork(char *, int);
 
57
extern unsigned short   level(int);
 
58
extern void             liima_mvgetnstr(int, int, char *, int);
 
59
extern void             multipmenu(void);
 
60
extern void             xcolor_set(short);
 
61
 
 
62
static int       dochange(int);
 
63
void             drawmenu(void);
 
64
void             drawscreen(void);
 
65
void             drawstatus(unsigned);
 
66
int              fileselmenu(int, struct finfo *, const char *);
 
67
static int       getnum(const char *, unsigned long, unsigned long);
 
68
void             initstatus(char *);
 
69
void             multipmenu(void);
 
70
void             nowordlist(void);
 
71
void             optionmenu(void);
 
72
void             pressanykey(int, int);
 
73
void             rulesmenu(void);
 
74
void             showhighscores(void);
 
75
void             tellstory(void);
 
76
 
 
77
extern int       misses;
 
78
extern char     *rankki[11];
 
79
 
 
80
struct positions {
 
81
        int rank;
 
82
        int score;
 
83
        int wpm;
 
84
        int speed;
 
85
        int misses;
 
86
} pos;
 
87
 
 
88
/* Switches "number" from 1 to 0 or any other value to 1. */
 
89
static int
 
90
dochange(int number)
 
91
{
 
92
        return (number == 1) ? 0 : 1;
 
93
}
 
94
 
 
95
/* Draws main menu onto screen. */
 
96
void
 
97
drawmenu(void)
 
98
{
 
99
        drawscreen();
 
100
 
 
101
        mvaddstr( 3, 30, "Typespeed ");
 
102
        addstr(TVERSION);
 
103
 
 
104
        mvaddstr( 5, 30, _("1. Test Your Speed"));
 
105
        if (opt.net == NET)
 
106
                mvaddstr( 6, 30, _("2. Close Connection"));
 
107
        else
 
108
                mvaddstr( 6, 30, _("2. Network Head2Head"));
 
109
        mvaddstr( 7, 30, _("3. Story/Credits/RTFM!"));
 
110
        mvaddstr( 8, 30, _("4. Show Highscores"));
 
111
        mvaddstr( 9, 30, _("5. Options"));
 
112
        mvaddstr(10, 30, _("6. Game Rules"));
 
113
        mvaddstr(11, 30, _("7. Quit"));
 
114
 
 
115
        mvaddstr(13, 30, _("Choose: "));
 
116
}
 
117
 
 
118
/* Clears screen and draws status bar. */
 
119
void
 
120
drawscreen(void)
 
121
{
 
122
        clear();
 
123
 
 
124
        xcolor_set(4);
 
125
        move(22, 0);
 
126
        hline(ACS_HLINE, 80);
 
127
        mvaddch(23, 1, '>');
 
128
        mvaddch(23, 21, '<');
 
129
 
 
130
        xcolor_set(5);
 
131
        mvaddstr(23, 23,
 
132
            _("Rank: %------- Score: %--- WPM: %-- CPS: %---- Misses: %-"));
 
133
 
 
134
        /* sets color to 2: NET, CHE need this */
 
135
        drawstatus(0);
 
136
 
 
137
        switch (opt.net) {
 
138
        case H2H:
 
139
                mvaddstr(22, 70, "H2H");
 
140
                break;
 
141
        case NET:
 
142
                mvaddstr(22, 70, "NET");
 
143
                break;
 
144
        default:
 
145
                break;
 
146
        }
 
147
 
 
148
        if (opt.cheat)
 
149
                mvaddstr(22, 73, "CHE");
 
150
 
 
151
        xcolor_set(5);
 
152
}
 
153
 
 
154
/*
 
155
 * Prints status values - no descriptions though!
 
156
 * Cursor will be put into "inputpos" (y = 21, x = 2 + inputpos).
 
157
 */
 
158
void
 
159
drawstatus(unsigned inputpos)
 
160
{
 
161
        mvprintw(23, pos.rank, "%-9s", rankki[level(now.score)]);
 
162
 
 
163
        xcolor_set(3);
 
164
        mvprintw(23, pos.score, "%4lu", now.score);
 
165
        mvprintw(23, pos.wpm, "%3lu", now.wpm);
 
166
        mvprintw(23, pos.speed, now.speed < 10.0f ? " %2.2f" : "%2.2f",
 
167
            now.speed);
 
168
        mvprintw(23, pos.misses, "%2lu", misses);
 
169
 
 
170
        xcolor_set(2);
 
171
        move(23, 2 + inputpos);
 
172
}
 
173
 
 
174
/* Prints file selection menu. */
 
175
int
 
176
fileselmenu(int tot, struct finfo *thingie, const char *title)
 
177
{
 
178
        int a, cpos, k;
 
179
 
 
180
        drawscreen();
 
181
        xcolor_set(4);
 
182
        mvprintw(2, 5, _("Choose a %s (UP/DOWN/ENTER):"), title);
 
183
        if (tot > 17)
 
184
                for (k = 0; k < 17; k++)
 
185
                        mvaddstr(k + 4, 5, thingie[k].descr);
 
186
        else
 
187
                for (k = 0; k < tot; k++)
 
188
                        mvaddstr(k + 4, 5, thingie[k].descr);
 
189
 
 
190
        cpos = k = 0;
 
191
        mvaddstr(4, 1, "->");
 
192
 
 
193
        for (a = 1; a;) {
 
194
                /*
 
195
                 * And thanks for xmunkki, he made my day and
 
196
                 * "solved" this, what i didn't get right (or did
 
197
                 * but i used 2 extra variables. :)
 
198
                 */
 
199
                switch (getch()) {
 
200
                case 27:
 
201
                        return -1;
 
202
                        break;
 
203
                case KEY_UP:
 
204
                case 'k':
 
205
                        if (k <= 0)
 
206
                                break;
 
207
                        k--;
 
208
                        if (cpos > 0) {
 
209
                                cpos--;
 
210
                                break;
 
211
                        }
 
212
                        move(20, 5);
 
213
                        deleteln();
 
214
                        move(4, 5);
 
215
                        insertln();
 
216
                        mvaddstr(4, 5, thingie[k].descr);
 
217
                        break;
 
218
                case KEY_DOWN:
 
219
                case 'j':
 
220
                        if (k > tot - 2)
 
221
                                break;
 
222
                        k++;
 
223
                        if (cpos < 16 && cpos < tot - 1) {
 
224
                                cpos++;
 
225
                                break;
 
226
                        }
 
227
                        move(4, 5);
 
228
                        deleteln();
 
229
                        move(20, 5);
 
230
                        insertln();
 
231
                        mvaddstr(20, 5, thingie[k].descr);
 
232
                        break;
 
233
                case ' ':
 
234
                case '\n':
 
235
                        a = 0;
 
236
                        break;
 
237
                default:
 
238
                        break;
 
239
                }
 
240
                mvaddstr(cpos + 3, 1, "  ");
 
241
                mvaddstr(cpos + 5, 1, "  ");
 
242
                mvaddstr(cpos + 4, 1, "->");
 
243
        }
 
244
 
 
245
        return k;
 
246
}
 
247
 
 
248
/*
 
249
 * Asks player about a specific value named by "string". If the entered
 
250
 * value is smaller or equal min, or larger or equal max, 0 is returned.
 
251
 * If a string (and not a number) has been entered, 0 is returned, too.
 
252
 *
 
253
 * Sets rules.hightype to 0, so a customized rule set cannot reach top10.
 
254
 */
 
255
static int
 
256
getnum(const char *string, unsigned long min, unsigned long max)
 
257
{
 
258
        unsigned long res;
 
259
        char entr[11];
 
260
        char clr[80];
 
261
 
 
262
        memset(clr, ' ', sizeof(clr));
 
263
        clr[sizeof(clr) - 1] = '\0';
 
264
 
 
265
        mvaddstr(17, 0, clr);
 
266
        mvaddstr(17, 30, string);
 
267
        liima_mvgetnstr(17, 31 + strlen(string), entr, sizeof(entr) - 1);
 
268
        entr[sizeof(entr) - 1] = '\0';
 
269
 
 
270
        if (!(res = cstrl(entr)) && errno)
 
271
                return 0;
 
272
        if (res > min && res < max) {
 
273
                rules.hightype = 0;
 
274
                return res;
 
275
        }
 
276
        return 0;
 
277
}
 
278
 
 
279
/*
 
280
 * Note places where rank, score, wpm, cps, and misses have to
 
281
 * be printed, so translators have a much easier job.
 
282
 *
 
283
 * "Rank: %------- Score: %--- WPM: %-- CPS: %----  Misses: %-"
 
284
 */
 
285
void
 
286
initstatus(char *str)
 
287
{
 
288
        int field;
 
289
        char *p;
 
290
 
 
291
        for (field = 0, p = str; *p != '\0'; p++) {
 
292
                if (*p != '%')
 
293
                        continue;
 
294
 
 
295
                switch (field) {
 
296
                case 0:
 
297
                        pos.rank = p - str + 23;
 
298
                        break;
 
299
                case 1:
 
300
                        pos.score = p - str + 23;
 
301
                        break;
 
302
                case 2:
 
303
                        pos.wpm = p - str + 23;
 
304
                        break;
 
305
                case 3:
 
306
                        pos.speed = p - str + 23;
 
307
                        break;
 
308
                case 4:
 
309
                        pos.misses = p - str + 23;
 
310
                        break;
 
311
                default:
 
312
                        xerrx(1, "1wrong status format");
 
313
                        /* NOTREACHED */
 
314
                }
 
315
                field++;
 
316
        }
 
317
 
 
318
        if (field != 5)
 
319
                xerrx(1, "2wrong status format");
 
320
}
 
321
 
 
322
/* Draws multiplayer menu. */
 
323
void
 
324
multipmenu(void)
 
325
{
 
326
        int exitnow;
 
327
        char port[6], serv[MAXHOSTNAMELEN];
 
328
 
 
329
        exitnow = 0;
 
330
        serv[0] = '\0';
 
331
 
 
332
        do {
 
333
                drawscreen();
 
334
                mvaddstr(3, 30, "Typespeed ");
 
335
                addstr(TVERSION);
 
336
 
 
337
                mvaddstr( 5, 30, _("1. Server"));
 
338
                mvaddstr( 6, 30, _("2. Client"));
 
339
                mvaddstr( 7, 30, _("3. Port"));
 
340
                mvaddstr( 8, 30, _("4. Player Name"));
 
341
                mvaddstr( 9, 30, _("5. Return"));
 
342
 
 
343
                xcolor_set(5);
 
344
                mvprintw( 7, 50, "%d", opt.port);
 
345
                mvprintw( 8, 50, "%s", opt.name);
 
346
                mvaddstr(11, 30, _("Choose: "));
 
347
 
 
348
                switch (getch()) {
 
349
                case '1':
 
350
                        serv[0] = '\0';
 
351
                        exitnow = 1;
 
352
                        break;
 
353
                case '2':
 
354
                        mvaddstr(11, 30, _("Enter Host:"));
 
355
                        liima_mvgetnstr(11, 31 +
 
356
                            strlen(_("Enter Host:")), serv,
 
357
                            sizeof(serv) - 1);
 
358
                        serv[sizeof(serv) - 1] = '\0';
 
359
                        exitnow = 1;
 
360
                        break;
 
361
                case '3':
 
362
                        mvaddstr(11, 30, _("Enter Port:"));
 
363
                        liima_mvgetnstr(11, 31 + strlen(_("Enter Port:")), port,
 
364
                            sizeof(port) - 1);
 
365
                        port[sizeof(port) - 1] = '\0';
 
366
                        opt.port = strtol(port, NULL, 10);
 
367
                        if (opt.port <= 1024)
 
368
                                opt.port = 6025;
 
369
                        exitnow = 0;
 
370
                        break;
 
371
                case '4':
 
372
                        mvaddstr(11, 30, _("Enter Name:"));
 
373
                        liima_mvgetnstr(11, 31 +
 
374
                            strlen(_("Enter Name:")), opt.name,
 
375
                            sizeof(opt.name) - 1);
 
376
                        opt.name[sizeof(opt.name) - 1] = '\0';
 
377
                        exitnow = 0;
 
378
                        break;
 
379
                case '5':
 
380
                        return;
 
381
                        /* NOTREACHED */
 
382
                        break;
 
383
                default:
 
384
                        break;
 
385
                }
 
386
        } while (!exitnow);
 
387
 
 
388
        drawscreen();
 
389
        mvaddstr(3, 30, "Typespeed ");
 
390
        addstr(TVERSION);
 
391
 
 
392
        mvaddstr(5, 30, _("When you get connect, choose a word list and"));
 
393
        mvaddstr(6, 30, _("then wait for the game start. The game starts as"));
 
394
        mvaddstr(7, 30, _("soon as the other player has chosen a word list."));
 
395
        refresh();
 
396
 
 
397
        initnetwork(serv, 1);
 
398
        flushinp();
 
399
}
 
400
 
 
401
/*
 
402
 * Prints "No word lists found...".
 
403
 * This function just exists to split all output out of file.c.
 
404
 */
 
405
void
 
406
nowordlist(void)
 
407
{
 
408
        drawscreen();
 
409
        mvaddstr(1, 5, _("No word lists found..."));
 
410
        pressanykey(3, 5);
 
411
}
 
412
 
 
413
/* Draws option menu. */
 
414
void
 
415
optionmenu(void)
 
416
{
 
417
        int wheretogo;
 
418
 
 
419
        do {
 
420
                drawscreen();
 
421
 
 
422
                mvaddstr(3, 30, "Typespeed ");
 
423
                addstr(TVERSION);
 
424
 
 
425
                mvaddstr(5, 30, _("1. Colors"));
 
426
                mvaddstr(6, 30, _("2. Cheat"));
 
427
                mvaddstr(7, 30, _("3. Return"));
 
428
 
 
429
                xcolor_set(3);
 
430
                if (opt.usecolors)
 
431
                        mvaddstr(5, 44, _("ON"));
 
432
                if (opt.cheat)
 
433
                        mvaddstr(6, 44, _("ON"));
 
434
 
 
435
                xcolor_set(6);
 
436
                if (!opt.usecolors)
 
437
                        mvaddstr(5, 44, _("OFF"));
 
438
                if (!opt.cheat)
 
439
                        mvaddstr(6, 44, _("OFF"));
 
440
 
 
441
                xcolor_set(5);
 
442
                mvaddstr(12, 30, _("Choose: "));
 
443
 
 
444
                switch (wheretogo = getch()) {
 
445
                case '2':
 
446
                        opt.cheat = dochange(opt.cheat);
 
447
                        break;
 
448
                case '1':
 
449
                        if (opt.usecolors)
 
450
                                xcolor_set(2);
 
451
                        opt.usecolors = dochange(opt.usecolors);
 
452
                        break;
 
453
                default:
 
454
                        break;
 
455
                }
 
456
        } while (wheretogo != '3');
 
457
}
 
458
 
 
459
/* This function waits until a key has been pressed */
 
460
void
 
461
pressanykey(int y, int x)
 
462
{
 
463
        flushinp();
 
464
        xcolor_set(4);
 
465
        mvaddstr(y, x, _("Press any key to continue..."));
 
466
        getch();
 
467
}
 
468
 
 
469
/* Draws rules menu. */
 
470
void
 
471
rulesmenu(void)
 
472
{
 
473
        int wheretogo;
 
474
        long tmp;
 
475
 
 
476
        do {
 
477
                drawscreen();
 
478
 
 
479
                mvaddstr( 3, 30, "Typespeed ");
 
480
                addstr(TVERSION);
 
481
 
 
482
                mvaddstr( 5, 30, _("Current Rule Set:"));
 
483
 
 
484
                mvaddstr( 7, 30, _("1. Load Another Rule Set"));
 
485
                mvaddstr( 8, 30, _("2. Misses Limit:"));
 
486
                mvaddstr( 9, 30, _("3. Word Length:"));
 
487
                addstr("    -");
 
488
                mvaddstr(10, 30, _("4. Words On Screen:"));
 
489
                addstr("    -");
 
490
                mvaddstr(11, 30, _("   High Score Enabled:"));
 
491
                mvaddstr(12, 30, _("6. Speed Step:"));
 
492
                mvaddstr(13, 30, _("7. Speed Range:"));
 
493
                addstr("    -");
 
494
                mvaddstr(14, 30, _("8. Smoothness:"));
 
495
                mvaddstr(15, 30, _("9. Return"));
 
496
 
 
497
                xcolor_set(3);
 
498
                mvprintw( 5, 31 + strlen(_("Current Rule Set:")), "%s",
 
499
                    rules.name);
 
500
                mvprintw( 8, 31 + strlen(_("2. Misses Limit:")), "%d",
 
501
                    rules.misses);
 
502
                mvprintw( 9, 31 + strlen(_("3. Word Length:")), "%2d",
 
503
                    rules.minlen);
 
504
                mvprintw( 9, 36 + strlen(_("3. Word Length:")), "%2d",
 
505
                    rules.maxlen);
 
506
                mvprintw(10, 31 + strlen(_("4. Words On Screen:")), "%2d",
 
507
                    rules.minwords);
 
508
                mvprintw(10, 36 + strlen(_("4. Words On Screen:")), "%2d",
 
509
                    rules.maxwords);
 
510
                if (rules.hightype)
 
511
                        mvaddstr(11, 31 + strlen(_("   High Score Enabled:")),
 
512
                            _("yes"));
 
513
                else
 
514
                        mvaddstr(11, 31 + strlen(_("   High Score Enabled:")),
 
515
                            _("no"));
 
516
                mvprintw(12, 31 + strlen(_("6. Speed Step:")), "%3d",
 
517
                    rules.step);
 
518
                mvprintw(13, 31 + strlen(_("7. Speed Range:")), "%2d",
 
519
                    rules.minspeed);
 
520
                if (rules.maxspeed)
 
521
                        mvprintw(13, 36 + strlen(_("7. Speed Range:")), "%2d",
 
522
                            rules.maxspeed);
 
523
                else
 
524
                        mvaddstr(13, 37 + strlen(_("7. Speed Range:")),
 
525
                            _("0 (unlimited)"));
 
526
                if (rules.smooth)
 
527
                        mvaddstr(14, 31 + strlen(_("8. Smoothness:")),
 
528
                            _("yes"));
 
529
                else
 
530
                        mvaddstr(14, 31 + strlen(_("8. Smoothness:")), _("no"));
 
531
                xcolor_set(5);
 
532
                mvaddstr(17, 30, _("Choose: "));
 
533
 
 
534
                switch (wheretogo = getch()) {
 
535
                case '1':
 
536
                        chooseruleset();
 
537
                        break;
 
538
                case '2':
 
539
                        if ((tmp = getnum(_("Misses Limit:"), 0, 100)))
 
540
                                rules.misses = tmp;
 
541
                        break;
 
542
                case '3':
 
543
                        if ((tmp = getnum(_("Min Length:"), 0, 20)))
 
544
                                rules.minlen = tmp;
 
545
                        if ((tmp = getnum(_("Max Length:"), 0, 20)))
 
546
                                rules.maxlen = tmp;
 
547
                        if (rules.minlen > rules.maxlen)
 
548
                                rules.maxlen = rules.minlen;
 
549
                        break;
 
550
                case '4':
 
551
                        if ((tmp = getnum(_("Min Words:"), 0, 23)))
 
552
                                rules.minwords = tmp;
 
553
                        if ((tmp = getnum(_("Max Words:"), 0, 23)))
 
554
                                rules.maxwords = tmp;
 
555
                        if (rules.minwords > rules.maxwords)
 
556
                                rules.maxwords = rules.minwords;
 
557
                        break;
 
558
                case '6':
 
559
                        if ((tmp = getnum(_("Speed Step:"), 0, 1000)))
 
560
                                rules.step = tmp;
 
561
                        break;
 
562
                case '7':
 
563
                        if ((tmp = getnum(_("Min Speed:"), 0, 100)))
 
564
                                rules.minspeed = tmp;
 
565
                        rules.maxspeed = getnum(_("Max Speed:"), 0, 100);
 
566
                        if (rules.minspeed > rules.maxspeed)
 
567
                                rules.maxspeed = 0;
 
568
                        break;
 
569
                case '8':
 
570
                        rules.smooth = dochange(rules.smooth);
 
571
                        rules.hightype = 0;
 
572
                        break;
 
573
                default:
 
574
                        break;
 
575
                }
 
576
        } while (wheretogo != '9');
 
577
}
 
578
 
 
579
/* Shows high scores. */
 
580
void
 
581
showhighscores(void)
 
582
{
 
583
        choosewordfile(1);
 
584
}
 
585
 
 
586
/* Draws credits onto screen. */
 
587
void
 
588
tellstory(void)
 
589
{
 
590
        drawscreen();
 
591
 
 
592
        mvaddstr( 3, 2, "Typespeed ");
 
593
        addstr(TVERSION);
 
594
        mvaddstr( 5, 2,
 
595
            _("Typespeed is made by  Jani Ollikainen  <bestis@iki.fi>"));
 
596
        mvaddstr( 6, 2,
 
597
            _("                    & Jaakko Manelius  <jman@iki.fi>"));
 
598
        mvaddstr( 7, 2,
 
599
            _("Current maintainer is Tobias Stoeckmann  <tobias@bugol.de>"));
 
600
 
 
601
        mvaddstr( 9, 2,
 
602
            _("Typespeed's idea is ripped from ztspeed (a dos game made"));
 
603
        mvaddstr(10, 2,
 
604
            _("by Zorlim). Typespeed doesn't give scores that can be"));
 
605
        mvaddstr(11, 2,
 
606
            _("compared with ztspeed anymore. We wanted to use our way."));
 
607
        mvaddstr(13, 2,
 
608
            _("Idea of the game should be clear to anyone, just type and"));
 
609
        mvaddstr(14, 2,
 
610
            _("type it fast, or be a lewser."));
 
611
        mvaddstr(16, 2,
 
612
            _("Bugs/Ideas/Comments to <tobias@bugol.de>"));
 
613
 
 
614
        pressanykey(18, 2);
 
615
}
 
616