Rev 4420 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4420 | Rev 4537 | ||
---|---|---|---|
Line 34... | Line 34... | ||
34 | * |
34 | * |
35 | * @(#)input.c 8.1 (Berkeley) 5/31/93 |
35 | * @(#)input.c 8.1 (Berkeley) 5/31/93 |
36 | */ |
36 | */ |
37 | 37 | ||
38 | /** @addtogroup tetris |
38 | /** @addtogroup tetris |
39 | * @{ |
39 | * @{ |
40 | */ |
40 | */ |
41 | /** @file |
41 | /** @file |
42 | */ |
42 | */ |
43 | 43 | ||
44 | /* |
44 | /* |
Line 55... | Line 55... | ||
55 | 55 | ||
56 | #include "input.h" |
56 | #include "input.h" |
57 | #include "tetris.h" |
57 | #include "tetris.h" |
58 | 58 | ||
59 | #include <async.h> |
59 | #include <async.h> |
- | 60 | #include <vfs/vfs.h> |
|
- | 61 | #include <io/console.h> |
|
60 | #include <ipc/console.h> |
62 | #include <ipc/console.h> |
61 | #include <console.h> |
- | |
62 | #include <kbd/kbd.h> |
- | |
63 | 63 | ||
64 | /* return true iff the given timeval is positive */ |
64 | /* return true iff the given timeval is positive */ |
65 | #define TV_POS(tv) \ |
65 | #define TV_POS(tv) \ |
66 | ((tv)->tv_sec > 0 || ((tv)->tv_sec == 0 && (tv)->tv_usec > 0)) |
66 | ((tv)->tv_sec > 0 || ((tv)->tv_sec == 0 && (tv)->tv_usec > 0)) |
67 | 67 | ||
Line 90... | Line 90... | ||
90 | * If tvp is nil, wait forever, but return if select is interrupted. |
90 | * If tvp is nil, wait forever, but return if select is interrupted. |
91 | * |
91 | * |
92 | * Return 0 => no input, 1 => can read() from stdin |
92 | * Return 0 => no input, 1 => can read() from stdin |
93 | * |
93 | * |
94 | */ |
94 | */ |
95 | int |
- | |
96 | rwait(struct timeval *tvp) |
95 | int rwait(struct timeval *tvp) |
97 | { |
96 | { |
98 | struct timeval starttv, endtv, *s; |
97 | struct timeval starttv, endtv, *s; |
99 | static ipc_call_t charcall; |
98 | static ipc_call_t charcall; |
100 | ipcarg_t rc; |
99 | ipcarg_t rc; |
101 | int cons_phone; |
- | |
102 | 100 | ||
103 | /* |
101 | /* |
104 | * Someday, select() will do this for us. |
102 | * Someday, select() will do this for us. |
105 | * Just in case that day is now, and no one has |
103 | * Just in case that day is now, and no one has |
106 | * changed this, we use a temporary. |
104 | * changed this, we use a temporary. |
107 | */ |
105 | */ |
Line 109... | Line 107... | ||
109 | (void) gettimeofday(&starttv, NULL); |
107 | (void) gettimeofday(&starttv, NULL); |
110 | endtv = *tvp; |
108 | endtv = *tvp; |
111 | s = &endtv; |
109 | s = &endtv; |
112 | } else |
110 | } else |
113 | s = NULL; |
111 | s = NULL; |
114 | 112 | ||
115 | if (!lastchar) { |
113 | if (!lastchar) { |
116 | again: |
114 | again: |
117 | if (!getchar_inprog) { |
115 | if (!getchar_inprog) { |
118 | cons_phone = console_open(true); |
- | |
119 | getchar_inprog = async_send_2(cons_phone, |
116 | getchar_inprog = async_send_0(fphone(stdin), |
120 | CONSOLE_GETKEY, 0, 0, &charcall); |
117 | CONSOLE_GET_EVENT, &charcall); |
121 | } |
118 | } |
- | 119 | ||
122 | if (!s) |
120 | if (!s) |
123 | async_wait_for(getchar_inprog, &rc); |
121 | async_wait_for(getchar_inprog, &rc); |
124 | else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) { |
122 | else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) { |
125 | tvp->tv_sec = 0; |
123 | tvp->tv_sec = 0; |
126 | tvp->tv_usec = 0; |
124 | tvp->tv_usec = 0; |
127 | return (0); |
125 | return (0); |
128 | } |
126 | } |
- | 127 | ||
129 | getchar_inprog = 0; |
128 | getchar_inprog = 0; |
130 | if (rc) { |
129 | if (rc) |
131 | stop("end of file, help"); |
130 | stop("end of file, help"); |
132 | } |
131 | |
133 | if (IPC_GET_ARG1(charcall) == KE_RELEASE) |
132 | if (IPC_GET_ARG1(charcall) == KEY_RELEASE) |
134 | goto again; |
133 | goto again; |
135 | 134 | ||
136 | lastchar = IPC_GET_ARG4(charcall); |
135 | lastchar = IPC_GET_ARG4(charcall); |
137 | } |
136 | } |
- | 137 | ||
138 | if (tvp) { |
138 | if (tvp) { |
139 | /* since there is input, we may not have timed out */ |
139 | /* since there is input, we may not have timed out */ |
140 | (void) gettimeofday(&endtv, NULL); |
140 | (void) gettimeofday(&endtv, NULL); |
141 | TV_SUB(&endtv, &starttv); |
141 | TV_SUB(&endtv, &starttv); |
142 | TV_SUB(tvp, &endtv); /* adjust *tvp by elapsed time */ |
142 | TV_SUB(tvp, &endtv); /* adjust *tvp by elapsed time */ |
143 | } |
143 | } |
- | 144 | ||
144 | return (1); |
145 | return 1; |
145 | } |
146 | } |
146 | 147 | ||
147 | /* |
148 | /* |
148 | * `sleep' for the current turn time (using select). |
149 | * `sleep' for the current turn time (using select). |
149 | * Eat any input that might be available. |
150 | * Eat any input that might be available. |
150 | */ |
151 | */ |
151 | void |
- | |
152 | tsleep(void) |
152 | void tsleep(void) |
153 | { |
153 | { |
154 | struct timeval tv; |
154 | struct timeval tv; |
155 | 155 | ||
156 | tv.tv_sec = 0; |
156 | tv.tv_sec = 0; |
157 | tv.tv_usec = fallrate; |
157 | tv.tv_usec = fallrate; |
158 | while (TV_POS(&tv)) |
158 | while (TV_POS(&tv)) |
159 | if (rwait(&tv)) { |
159 | if (rwait(&tv)) { |
160 | lastchar = '\0'; |
160 | lastchar = '\0'; |
Line 163... | Line 163... | ||
163 | } |
163 | } |
164 | 164 | ||
165 | /* |
165 | /* |
166 | * getchar with timeout. |
166 | * getchar with timeout. |
167 | */ |
167 | */ |
168 | int |
- | |
169 | tgetchar(void) |
168 | int tgetchar(void) |
170 | { |
169 | { |
171 | static struct timeval timeleft; |
170 | static struct timeval timeleft; |
172 | char c; |
171 | char c; |
173 | 172 | ||
174 | /* |
173 | /* |
175 | * Reset timeleft to fallrate whenever it is not positive. |
174 | * Reset timeleft to fallrate whenever it is not positive. |
176 | * In any case, wait to see if there is any input. If so, |
175 | * In any case, wait to see if there is any input. If so, |
177 | * take it, and update timeleft so that the next call to |
176 | * take it, and update timeleft so that the next call to |
178 | * tgetchar() will not wait as long. If there is no input, |
177 | * tgetchar() will not wait as long. If there is no input, |
179 | * make timeleft zero or negative, and return -1. |
178 | * make timeleft zero or negative, and return -1. |
180 | * |
179 | * |
181 | * Most of the hard work is done by rwait(). |
180 | * Most of the hard work is done by rwait(). |
182 | */ |
181 | */ |
183 | if (!TV_POS(&timeleft)) { |
182 | if (!TV_POS(&timeleft)) { |
184 | faster(); /* go faster */ |
183 | faster(); /* go faster */ |
185 | timeleft.tv_sec = 0; |
184 | timeleft.tv_sec = 0; |
186 | timeleft.tv_usec = fallrate; |
185 | timeleft.tv_usec = fallrate; |
187 | } |
186 | } |
- | 187 | ||
188 | if (!rwait(&timeleft)) |
188 | if (!rwait(&timeleft)) |
189 | return (-1); |
189 | return -1; |
- | 190 | ||
190 | c = lastchar; |
191 | c = lastchar; |
191 | lastchar = '\0'; |
192 | lastchar = '\0'; |
192 | return ((int)(unsigned char)c); |
193 | return ((int) (unsigned char) c); |
193 | } |
194 | } |
194 | 195 | ||
195 | /** @} |
196 | /** @} |
196 | */ |
197 | */ |
197 | - |