996
|
1 /*
|
|
2 * Copyright (c) 2004, 2005 Gregor Richards
|
|
3 *
|
|
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5 * of this software and associated documentation files (the "Software"), to deal
|
|
6 * in the Software without restriction, including without limitation the rights
|
|
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8 * copies of the Software, and to permit persons to whom the Software is
|
|
9 * furnished to do so, subject to the following conditions:
|
|
10 *
|
|
11 * The above copyright notice and this permission notice shall be included in
|
|
12 * all copies or substantial portions of the Software.
|
|
13 *
|
|
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20 * SOFTWARE.
|
|
21 */
|
|
22
|
|
23 #include <stdio.h>
|
|
24 #include <stdlib.h>
|
|
25 #include <string.h>
|
|
26 #include <unistd.h>
|
|
27
|
|
28 #define XY(x,y) (((y)*1024)+(x))
|
|
29
|
|
30 int main(int argc, char **argv)
|
|
31 {
|
|
32 char pbuf[1024*1024];
|
|
33 int px, py, oy;
|
|
34 int vx, vy, vye;
|
|
35 int ovx = 1024;
|
|
36 int ovy = 1024;
|
|
37 int dir;
|
|
38 char prev;
|
|
39
|
|
40 char mbuf[32256];
|
|
41 int mloc;
|
|
42
|
|
43 FILE *pinp;
|
|
44 char pline[1024];
|
|
45
|
|
46 int dlev;
|
|
47 char *outbuf;
|
|
48
|
|
49 if (argc < 2) {
|
|
50 printf("Use: %s <program>\n", argv[0]);
|
|
51 return 1;
|
|
52 }
|
|
53
|
|
54 /* get debug level */
|
|
55 if (argc > 2) {
|
|
56 dlev = atoi(argv[2]);
|
|
57 outbuf = (char *) malloc(32256);
|
|
58 outbuf[0] = '\0';
|
|
59 } else {
|
|
60 outbuf = NULL;
|
|
61 dlev = 0;
|
|
62 }
|
|
63
|
|
64 memset(pbuf, 0, 1024*1024);
|
|
65 py = 0;
|
|
66
|
|
67 /* read in the file */
|
|
68 pinp = fopen(argv[1], "r");
|
|
69 if (pinp == NULL) {
|
|
70 perror("fopen");
|
|
71 return 1;
|
|
72 }
|
|
73
|
|
74 while (!feof(pinp)) {
|
|
75 int ostrlen;
|
|
76
|
|
77 fgets(pline, 1024, pinp);
|
|
78
|
|
79 ostrlen = strlen(pline);
|
|
80 if (pline[ostrlen-1] == '\n') {
|
|
81 pline[ostrlen-1] = '\0';
|
|
82 }
|
|
83
|
|
84 strcpy(pbuf + XY(0, py), pline);
|
|
85 py++;
|
|
86 }
|
|
87
|
|
88 fclose(pinp);
|
|
89
|
|
90
|
|
91 px = 0;
|
|
92 py = 0;
|
|
93 dir = 3;
|
|
94
|
|
95 memset(mbuf, 0, 32256);
|
|
96 mloc = 2;
|
|
97
|
|
98 while (1) {
|
|
99 switch(pbuf[XY(px, py)]) {
|
|
100 case '+': /* branch */
|
|
101 /* go back */
|
|
102 switch (dir) {
|
|
103 case 1: /* up */
|
|
104 py++;
|
|
105 break;
|
|
106 case 2: /* right */
|
|
107 px--;
|
|
108 break;
|
|
109 case 3: /* down */
|
|
110 py--;
|
|
111 break;
|
|
112 case 4: /* left */
|
|
113 px++;
|
|
114 break;
|
|
115 }
|
|
116
|
|
117 if (mbuf[mloc]) {
|
|
118 dir++;
|
|
119 } else {
|
|
120 dir--;
|
|
121 }
|
|
122
|
|
123 if (dir == 0) dir = 4;
|
|
124 if (dir == 5) dir = 1;
|
|
125 break;
|
|
126
|
|
127 case '*': /* memory operator */
|
|
128 if (mloc == 1 && (dir == 2 || dir == 4)) {
|
|
129 /* IO */
|
|
130 if (mbuf[0] == 0) { /* input */
|
|
131 mbuf[0] = getchar();
|
|
132 } else { /* output */
|
|
133 /* if debugging, buffer output */
|
|
134 if (dlev != 0) {
|
|
135 sprintf(outbuf+strlen(outbuf), "%c", mbuf[0]);
|
|
136 } else {
|
|
137 putchar(mbuf[0]);
|
|
138 fflush(stdout);
|
|
139 }
|
|
140 mbuf[0] = 0;
|
|
141 }
|
|
142 } else { /* not IO */
|
|
143 switch (dir) {
|
|
144 case 1: /* up */
|
|
145 mloc--;
|
|
146 break;
|
|
147 case 2: /* right */
|
|
148 mbuf[mloc]++;
|
|
149 break;
|
|
150 case 3: /* down */
|
|
151 mloc++;
|
|
152 break;
|
|
153 case 4: /* left */
|
|
154 mbuf[mloc]--;
|
|
155 break;
|
|
156 }
|
|
157 }
|
|
158 break;
|
|
159 }
|
|
160
|
|
161 /* if debugging, output */
|
|
162 if (dlev != 0) {
|
|
163 /*system("clear");*/
|
|
164
|
|
165 /* center with a screen at 80x25 */
|
|
166 vx = px / 40;
|
|
167 vx *= 40;
|
|
168 vx -= 40;
|
|
169 vx = (vx < 0) ? 0 : vx;
|
|
170 vy = py / 12;
|
|
171 vy *= 12;
|
|
172 vy -= 12;
|
|
173 vy = (vy < 0) ? 0 : vy;
|
|
174 vye = vy + 25;
|
|
175
|
|
176 /* only blank the screen if necessary */
|
|
177 if (ovx != vx || ovy != vy) {
|
|
178 printf("\033[2J"); /* clear the screen */
|
|
179 fflush(stdout);
|
|
180 }
|
|
181 ovx = vx;
|
|
182 ovy = vy;
|
|
183
|
|
184 printf("\033[0;0f"); /* go to the top-left */
|
|
185 fflush(stdout);
|
|
186
|
|
187 prev = pbuf[XY(px, py)];
|
|
188 pbuf[XY(px, py)] = '@';
|
|
189 for (oy = vy; pbuf[XY(0, oy)] != '\0' && oy <= vye; oy++) {
|
|
190 printf("%.*s\n", 80, pbuf + XY(vx, oy));
|
|
191 }
|
|
192 pbuf[XY(px, py)] = prev;
|
|
193
|
|
194 printf("\n%s\n", outbuf);
|
|
195
|
|
196 usleep(1000000 / dlev);
|
|
197 }
|
|
198
|
|
199 /* now move */
|
|
200 switch (dir) {
|
|
201 case 1: /* up */
|
|
202 py--;
|
|
203 break;
|
|
204 case 2: /* right */
|
|
205 px++;
|
|
206 break;
|
|
207 case 3: /* down */
|
|
208 py++;
|
|
209 break;
|
|
210 case 4: /* left */
|
|
211 px--;
|
|
212 break;
|
|
213 }
|
|
214
|
|
215 /* quit if < 0 */
|
|
216 if (px < 0 || py < 0) {
|
|
217 return 0;
|
|
218 }
|
|
219 }
|
|
220 }
|