Rev 4348 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4348 | Rev 4691 | ||
|---|---|---|---|
| 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 | - | ||