Subversion Repositories HelenOS-historic

Rev

Rev 1519 | Rev 1528 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1519 Rev 1524
Line 44... Line 44...
44
#include <stdlib.h>
44
#include <stdlib.h>
45
#include <string.h>
45
#include <string.h>
46
#include <unistd.h>
46
#include <unistd.h>
47
#include <io/stream.h>
47
#include <io/stream.h>
48
 
48
 
-
 
49
 
-
 
50
#include <async.h>
49
#include "screen.h"
51
#include "screen.h"
50
#include "tetris.h"
52
#include "tetris.h"
-
 
53
#include "../console/console.h"
51
 
54
 
52
static cell curscreen[B_SIZE];  /* 1 => standout (or otherwise marked) */
55
static cell curscreen[B_SIZE];  /* 1 => standout (or otherwise marked) */
53
static int curscore;
56
static int curscore;
54
static int isset;       /* true => terminal is in game mode */
57
static int isset;       /* true => terminal is in game mode */
55
static struct termios oldtt;
58
static struct termios oldtt;
56
static void (*tstp)(int);
59
static void (*tstp)(int);
57
 
60
 
58
static void scr_stop(int);
61
static void scr_stop(int);
59
static void stopset(int);
62
static void stopset(int);
60
 
63
 
-
 
64
static char
-
 
65
        *CEstr;         /* clear to end of line */
-
 
66
 
-
 
67
 
61
/*
68
/*
-
 
69
 * putstr() is for unpadded strings (either as in termcap(5) or
62
 * Capabilities from TERMCAP.
70
 * simply literal strings);
63
 */
71
 */
64
char    PC, *BC, *UP;       /* tgoto requires globals: ugh! */
72
#define putstr(s)   puts(s)
65
 
73
 
66
static char
-
 
67
    *bcstr,         /* backspace char */
-
 
68
    *CEstr,         /* clear to end of line */
-
 
69
    *CLstr,         /* clear screen */
-
 
70
    *CMstr,         /* cursor motion string */
-
 
71
#ifdef unneeded
-
 
72
    *CRstr,         /* "\r" equivalent */
-
 
73
#endif
-
 
74
    *HOstr,         /* cursor home */
-
 
75
    *LLstr,         /* last line, first column */
-
 
76
    *pcstr,         /* pad character */
-
 
77
    *TEstr,         /* end cursor motion mode */
-
 
78
    *TIstr;         /* begin cursor motion mode */
-
 
79
char
-
 
80
    *SEstr,         /* end standout mode */
-
 
81
    *SOstr;         /* begin standout mode */
-
 
82
static int
74
static int con_phone;
83
    COnum,          /* co# value */
-
 
84
    LInum,          /* li# value */
-
 
85
    MSflag;         /* can move in standout mode */
-
 
86
 
-
 
87
 
-
 
88
struct tcsinfo {        /* termcap string info; some abbrevs above */
-
 
89
    char tcname[3];
-
 
90
    char **tcaddr;
-
 
91
} tcstrings[] = {
-
 
92
    {"bc", &bcstr},
-
 
93
    {"ce", &CEstr},
-
 
94
    {"cl", &CLstr},
-
 
95
    {"cm", &CMstr},
-
 
96
#ifdef unneeded
-
 
97
    {"cr", &CRstr},
-
 
98
#endif
-
 
99
    {"le", &BC},        /* move cursor left one space */
-
 
100
    {"pc", &pcstr},
-
 
101
    {"se", &SEstr},
-
 
102
    {"so", &SOstr},
-
 
103
    {"te", &TEstr},
-
 
104
    {"ti", &TIstr},
-
 
105
    {"up", &UP},        /* cursor up */
-
 
106
    { {0}, NULL}
-
 
107
};
-
 
108
 
75
 
109
/* This is where we will actually stuff the information */
-
 
110
 
76
 
111
static char combuf[1024], tbuf[1024];
-
 
112
 
77
 
-
 
78
static void set_style(int fgcolor, int bgcolor)
-
 
79
{
-
 
80
    send_call_2(con_phone, CONSOLE_SET_STYLE, fgcolor, bgcolor);
-
 
81
}
113
 
82
 
114
/*
-
 
115
 * Routine used by tputs().
83
static void start_standout(void)
116
 */
-
 
117
int
-
 
118
put(int c)
-
 
119
{
84
{
-
 
85
    set_style(0, 0xe0e0e0);
-
 
86
}
120
 
87
 
-
 
88
static void resume_normal(void)
-
 
89
{
121
    return (putchar(c));
90
    set_style(0xe0e0e0, 0);
122
}
91
}
123
 
92
 
124
/*
93
/*
125
 * putstr() is for unpadded strings (either as in termcap(5) or
94
 * Clear the screen, forgetting the current contents in the process.
126
 * simply literal strings); putpad() is for padded strings with
-
 
127
 * count=1.  (See screen.h for putpad().)
-
 
128
 */
95
 */
-
 
96
void
129
#define putstr(s)   (void)fputs(s, stdout)
97
scr_clear(void)
130
#define moveto(r, c)    putpad(tgoto(CMstr, c, r))
-
 
-
 
98
{
131
 
99
 
-
 
100
    send_call(con_phone, CONSOLE_CLEAR, 0);
132
static int con_phone;
101
    curscore = -1;
-
 
102
    memset((char *)curscreen, 0, sizeof(curscreen));
-
 
103
}
133
 
104
 
134
/*
105
/*
135
 * Set up from termcap.
106
 * Set up screen
136
 */
107
 */
137
void
108
void
138
scr_init(void)
109
scr_init(void)
139
{
110
{
140
    con_phone = get_fd_phone(1);
111
    con_phone = get_fd_phone(1);
-
 
112
    resume_normal();
-
 
113
    scr_clear();
-
 
114
}
-
 
115
 
-
 
116
static void moveto(int r, int c)
-
 
117
{
-
 
118
    send_call_2(con_phone, CONSOLE_GOTO, r, c);
-
 
119
}
-
 
120
 
-
 
121
static void fflush(void)
-
 
122
{
-
 
123
    send_call(con_phone, CONSOLE_FLUSH, 0);
141
}
124
}
142
 
125
 
-
 
126
struct winsize {
-
 
127
    ipcarg_t ws_row;
-
 
128
    ipcarg_t ws_col;
-
 
129
};
-
 
130
 
-
 
131
static int get_display_size(struct winsize *ws)
-
 
132
{
-
 
133
    return sync_send_2(con_phone, CONSOLE_GETSIZE, 0, 0, &ws->ws_row, &ws->ws_col);
-
 
134
}
143
 
135
 
144
static void
136
static void
145
scr_stop(int sig)
137
scr_stop(int sig)
146
{
138
{
147
 
139
 
Line 155... Line 147...
155
 */
147
 */
156
void
148
void
157
scr_set(void)
149
scr_set(void)
158
{
150
{
159
    struct winsize ws;
151
    struct winsize ws;
160
    struct termios newtt;
-
 
161
    void (*ttou)(int);
-
 
162
 
152
 
163
    Rows = 0, Cols = 0;
153
    Rows = 0, Cols = 0;
164
    if (ioctl(0, TIOCGWINSZ, &ws) == 0) {
154
    if (get_display_size(&ws) == 0) {
165
        Rows = ws.ws_row;
155
        Rows = ws.ws_row;
166
        Cols = ws.ws_col;
156
        Cols = ws.ws_col;
167
    }
157
    }
168
    if (Rows == 0)
-
 
169
        Rows = LInum;
-
 
170
    if (Cols == 0)
-
 
171
    Cols = COnum;
-
 
172
    if (Rows < MINROWS || Cols < MINCOLS) {
158
    if (Rows < MINROWS || Cols < MINCOLS) {
173
        char smallscr[55];
159
        char smallscr[55];
174
 
160
 
175
        (void)snprintf(smallscr, sizeof(smallscr),
161
        (void)snprintf(smallscr, sizeof(smallscr),
176
            "the screen is too small (must be at least %dx%d)",
162
            "the screen is too small (must be at least %dx%d)",
177
            MINROWS, MINCOLS);
163
            MINROWS, MINCOLS);
178
        stop(smallscr);
164
        stop(smallscr);
179
    }
165
    }
180
    if (tcgetattr(0, &oldtt) < 0)
-
 
181
        stop("tcgetattr() fails");
-
 
182
    newtt = oldtt;
-
 
183
    newtt.c_lflag &= ~(ICANON|ECHO);
-
 
184
    newtt.c_oflag &= ~OXTABS;
-
 
185
    if (tcsetattr(0, TCSADRAIN, &newtt) < 0)
-
 
186
        stop("tcsetattr() fails");
-
 
187
 
-
 
188
    /*
-
 
189
     * We made it.  We are now in screen mode, modulo TIstr
-
 
190
     * (which we will fix immediately).
-
 
191
     */
-
 
192
    if (TIstr)
-
 
193
        putstr(TIstr);  /* termcap(5) says this is not padded */
-
 
194
 
-
 
195
    isset = 1;
166
    isset = 1;
196
 
167
 
197
    scr_clear();
168
    scr_clear();
198
}
169
}
199
 
170
 
Line 212... Line 183...
212
    if (isset)
183
    if (isset)
213
        scr_end();
184
        scr_end();
214
    errx(1, "aborting: %s", why);
185
    errx(1, "aborting: %s", why);
215
}
186
}
216
 
187
 
217
/*
-
 
218
 * Clear the screen, forgetting the current contents in the process.
-
 
219
 */
-
 
220
void
-
 
221
scr_clear(void)
-
 
222
{
-
 
223
 
-
 
224
    putpad(CLstr);
-
 
225
    curscore = -1;
-
 
226
    memset((char *)curscreen, 0, sizeof(curscreen));
-
 
227
}
-
 
228
 
188
 
229
#if vax && !__GNUC__
189
#if vax && !__GNUC__
230
typedef int regcell;    /* pcc is bad at `register char', etc */
190
typedef int regcell;    /* pcc is bad at `register char', etc */
231
#else
191
#else
232
typedef cell regcell;
192
typedef cell regcell;
Line 245... Line 205...
245
 
205
 
246
    /* always leave cursor after last displayed point */
206
    /* always leave cursor after last displayed point */
247
    curscreen[D_LAST * B_COLS - 1] = -1;
207
    curscreen[D_LAST * B_COLS - 1] = -1;
248
 
208
 
249
    if (score != curscore) {
209
    if (score != curscore) {
250
        if (HOstr)
-
 
251
            putpad(HOstr);
-
 
252
        else
-
 
253
            moveto(0, 0);
210
        moveto(0, 0);
254
        (void) printf("Score: %d", score);
211
        (void) printf("Score: %d", score);
255
        curscore = score;
212
        curscore = score;
256
    }
213
    }
257
 
214
 
258
    /* draw preview of next pattern */
215
    /* draw preview of next pattern */
Line 262... Line 219...
262
        int tr, tc, t;
219
        int tr, tc, t;
263
 
220
 
264
        lastshape = nextshape;
221
        lastshape = nextshape;
265
 
222
 
266
        /* clean */
223
        /* clean */
267
        putpad(SEstr);
224
        resume_normal();
268
        moveto(r-1, c-1); putstr("          ");
225
        moveto(r-1, c-1); putstr("          ");
269
        moveto(r,   c-1); putstr("          ");
226
        moveto(r,   c-1); putstr("          ");
270
        moveto(r+1, c-1); putstr("          ");
227
        moveto(r+1, c-1); putstr("          ");
271
        moveto(r+2, c-1); putstr("          ");
228
        moveto(r+2, c-1); putstr("          ");
272
 
229
 
273
        moveto(r-3, c-2);
230
        moveto(r-3, c-2);
274
        putstr("Next shape:");
231
        putstr("Next shape:");
275
 
232
 
276
        /* draw */
233
        /* draw */
277
        if (SOstr)
-
 
278
            putpad(SOstr);
234
        start_standout();
279
        moveto(r, 2 * c);
235
        moveto(r, 2 * c);
280
        putstr(SOstr ? "  " : "[]");
236
        putstr("  ");
281
        for (i = 0; i < 3; i++) {
237
        for (i = 0; i < 3; i++) {
282
            t = c + r * B_COLS;
238
            t = c + r * B_COLS;
283
            t += nextshape->off[i];
239
            t += nextshape->off[i];
284
 
240
 
285
            tr = t / B_COLS;
241
            tr = t / B_COLS;
286
            tc = t % B_COLS;
242
            tc = t % B_COLS;
287
 
243
 
288
            moveto(tr, 2*tc);
244
            moveto(tr, 2*tc);
289
            putstr(SOstr ? "  " : "[]");
245
            putstr("  ");
290
        }
246
        }
291
        putpad(SEstr);
247
        resume_normal();
292
    }
248
    }
293
 
249
 
294
    bp = &board[D_FIRST * B_COLS];
250
    bp = &board[D_FIRST * B_COLS];
295
    sp = &curscreen[D_FIRST * B_COLS];
251
    sp = &curscreen[D_FIRST * B_COLS];
296
    for (j = D_FIRST; j < D_LAST; j++) {
252
    for (j = D_FIRST; j < D_LAST; j++) {
Line 298... Line 254...
298
        for (i = 0; i < B_COLS; bp++, sp++, i++) {
254
        for (i = 0; i < B_COLS; bp++, sp++, i++) {
299
            if (*sp == (so = *bp))
255
            if (*sp == (so = *bp))
300
                continue;
256
                continue;
301
            *sp = so;
257
            *sp = so;
302
            if (i != ccol) {
258
            if (i != ccol) {
303
                if (cur_so && MSflag) {
-
 
304
                    putpad(SEstr);
-
 
305
                    cur_so = 0;
-
 
306
                }
-
 
307
                moveto(RTOD(j), CTOD(i));
259
                moveto(RTOD(j), CTOD(i));
308
            }
260
            }
309
            if (SOstr) {
261
            if (so != cur_so) {
310
                if (so != cur_so) {
262
                if (so)
311
                    putpad(so ? SOstr : SEstr);
263
                    start_standout();
-
 
264
                else
-
 
265
                    resume_normal();
312
                    cur_so = so;
266
                cur_so = so;
313
                }
267
            }
314
                putstr("  ");
268
            putstr("  ");
315
            } else
-
 
316
                putstr(so ? "[]" : "  ");
-
 
317
            ccol = i + 1;
269
            ccol = i + 1;
318
            /*
270
            /*
319
             * Look ahead a bit, to avoid extra motion if
271
             * Look ahead a bit, to avoid extra motion if
320
             * we will be redrawing the cell after the next.
272
             * we will be redrawing the cell after the next.
321
             * Motion probably takes four or more characters,
273
             * Motion probably takes four or more characters,
Line 332... Line 284...
332
                sp[2] = -1;
284
                sp[2] = -1;
333
                sp[1] = -1;
285
                sp[1] = -1;
334
            }
286
            }
335
        }
287
        }
336
    }
288
    }
337
    if (cur_so)
-
 
338
        putpad(SEstr);
289
    resume_normal();
-
 
290
 
339
/*  (void) fflush(stdout); */
291
    fflush();
340
/*  (void) sigprocmask(SIG_SETMASK, &osigset, (sigset_t *)0); */
-
 
341
}
292
}
342
 
293
 
343
/*
294
/*
344
 * Write a message (set!=0), or clear the same message (set==0).
295
 * Write a message (set!=0), or clear the same message (set==0).
345
 * (We need its length in case we have to overwrite with blanks.)
296
 * (We need its length in case we have to overwrite with blanks.)