]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - cgram/cgram.c
2 * Copyright (c) 2013 The NetBSD Foundation, Inc.
5 * This code is derived from software contributed to The NetBSD Foundation
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
38 #include "pathnames.h"
40 ////////////////////////////////////////////////////////////
42 static char *xstrdup(const char *s
) {
45 ret
= malloc(strlen(s
) + 1);
47 errx(1, "Out of memory");
53 ////////////////////////////////////////////////////////////
60 static void stringarray_init(struct stringarray
*a
) {
65 static void stringarray_cleanup(struct stringarray
*a
) {
69 static void stringarray_add(struct stringarray
*a
, const char *s
) {
70 a
->v
= realloc(a
->v
, (a
->num
+ 1) * sizeof(a
->v
[0]));
72 errx(1, "Out of memory");
74 a
->v
[a
->num
] = xstrdup(s
);
78 ////////////////////////////////////////////////////////////
80 static struct stringarray lines
;
81 static struct stringarray sollines
;
83 static int scrolldown
;
87 static void readquote(void) {
88 FILE *f
= popen(_PATH_FORTUNE
, "r");
90 err(1, "%s", _PATH_FORTUNE
);
93 char buf
[128], buf2
[8*sizeof(buf
)];
94 while (fgets(buf
, sizeof(buf
), f
)) {
95 char *s
= strrchr(buf
, '\n');
101 for (i
=j
=0; buf
[i
]; i
++) {
104 while (j%8
) buf2
[j
++] = ' ';
106 else if (buf
[i
]=='\b') {
115 stringarray_add(&lines
, buf2
);
116 stringarray_add(&sollines
, buf2
);
122 static void encode(void) {
124 for (int i
=0; i
<26; i
++) used
[i
] = 0;
128 while (keypos
< 26) {
130 if (used
[c
]) continue;
135 for (int y
=0; y
<lines
.num
; y
++) {
136 for (unsigned x
=0; lines
.v
[y
][x
]; x
++) {
137 if (islower((unsigned char)lines
.v
[y
][x
])) {
138 int q
= lines
.v
[y
][x
]-'a';
139 lines
.v
[y
][x
] = 'a'+key
[q
];
141 if (isupper((unsigned char)lines
.v
[y
][x
])) {
142 int q
= lines
.v
[y
][x
]-'A';
143 lines
.v
[y
][x
] = 'A'+key
[q
];
149 static int substitute(int ch
) {
150 assert(cury
>=0 && cury
<lines
.num
);
151 if (curx
>= strlen(lines
.v
[cury
])) {
156 int och
= lines
.v
[cury
][curx
];
157 if (!isalpha((unsigned char)och
)) {
162 int loch
= tolower((unsigned char)och
);
163 int uoch
= toupper((unsigned char)och
);
164 int lch
= tolower((unsigned char)ch
);
165 int uch
= toupper((unsigned char)ch
);
167 for (int y
=0; y
<lines
.num
; y
++) {
168 for (unsigned x
=0; lines
.v
[y
][x
]; x
++) {
169 if (lines
.v
[y
][x
]==loch
) {
172 else if (lines
.v
[y
][x
]==uoch
) {
175 else if (lines
.v
[y
][x
]==lch
) {
176 lines
.v
[y
][x
] = loch
;
178 else if (lines
.v
[y
][x
]==uch
) {
179 lines
.v
[y
][x
] = uoch
;
186 ////////////////////////////////////////////////////////////
188 static void redraw(void) {
191 for (int i
=0; i
<LINES
-1; i
++) {
193 int ln
= i
+scrolldown
;
194 if (ln
< lines
.num
) {
195 for (unsigned j
=0; lines
.v
[i
][j
]; j
++) {
196 int ch
= lines
.v
[i
][j
];
197 if (ch
!= sollines
.v
[i
][j
] && isalpha((unsigned char)ch
)) {
201 if (hinting
&& ch
==sollines
.v
[i
][j
] &&
202 isalpha((unsigned char)ch
)) {
206 addch(lines
.v
[i
][j
]);
219 addstr("~ to quit, * to cheat, ^pnfb to move");
223 move(cury
-scrolldown
, curx
);
228 static void opencurses(void) {
234 static void closecurses(void) {
238 ////////////////////////////////////////////////////////////
240 static void loop(void) {
255 curx
= strlen(lines
.v
[cury
]);
259 curx
= strlen(lines
.v
[cury
]);
262 if (curx
< strlen(lines
.v
[cury
])) {
265 else if (cury
< lines
.num
- 1) {
274 if (cury
< lines
.num
-1) {
277 if (curx
> strlen(lines
.v
[cury
])) {
278 curx
= strlen(lines
.v
[cury
]);
280 if (scrolldown
< cury
- (LINES
-2)) {
281 scrolldown
= cury
- (LINES
-2);
288 if (curx
> strlen(lines
.v
[cury
])) {
289 curx
= strlen(lines
.v
[cury
]);
291 if (scrolldown
> cury
) {
303 if (!substitute(ch
)) {
304 if (curx
< strlen(lines
.v
[cury
])) {
307 if (curx
==strlen(lines
.v
[cury
]) && cury
< lines
.num
-1) {
313 else if (curx
< strlen(lines
.v
[cury
]) && ch
==lines
.v
[cury
][curx
]) {
315 if (curx
==strlen(lines
.v
[cury
]) && cury
< lines
.num
-1) {
328 ////////////////////////////////////////////////////////////
331 stringarray_init(&lines
);
332 stringarray_init(&sollines
);
341 stringarray_cleanup(&sollines
);
342 stringarray_cleanup(&lines
);