forked from TheGLander/tworld
-
Notifications
You must be signed in to change notification settings - Fork 0
/
help.c
334 lines (313 loc) · 11.8 KB
/
help.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
/* help.c: Displaying online help.
*
* Copyright (C) 2001-2010 by Brian Raiter and Madhav Shanbhag,
* under the GNU General Public License. No warranty. See COPYING for details.
*/
#include <stdlib.h>
#include "defs.h"
#include "err.h"
#include "state.h"
#include "oshw.h"
#include "ver.h"
#include "comptime.h"
#include "help.h"
#define COUNTOF(a) (sizeof(a) / sizeof(*a))
#define ARRAY(a) a, COUNTOF(a)
/* Help for command-line options.
*/
static char const *yowzitch_items[] = {
"1-Usage:", "1!tworld [-hvVdlsbtpqrPFa] [-n N] [-DLRS DIR] "
"[NAME] [SNAME] [LEVEL]",
"1- -D", "1!Read data files from DIR instead of the default.",
"1- -L", "1!Read level sets from DIR instead of the default.",
"1- -R", "1!Read resource files from DIR instead of the default.",
"1- -S", "1!Save games and settings in DIR instead of the default.",
"1- -p", "1!Disable password checking.",
"1- -F", "1!Run in fullscreen mode.",
"1- -q", "1!Run quietly.",
"1- -r", "1!Run in read-only mode; solutions will not be saved.",
"1- -P", "1!Put Lynx ruleset emulation in pedantic mode.",
"1- -n", "1!Set initial volume level to N.",
"1- -a", "1!Double the size of the sound buffer (can be repeated).",
"1- -l", "1!Display the list of available data files and exit.",
"1- -s", "1!Display scores for the selected data file and exit.",
"1- -t", "1!Display times for the selected data file and exit.",
"1- -b", "1!Batch-verify solutions for the selected data file and exit.",
"1- -h", "1!Display this help and exit.",
"1- -d", "1!Display default directories and exit.",
"1- -v", "1!Display version number and exit.",
"1- -V", "1!Display version and license information and exit.",
"2!NAME specifies which data file to use.",
"2!LEVEL specifies which level to start at.",
"2!SNAME specifies an alternate solution file."
};
static tablespec const yowzitch_table = { 23, 2, 2, -1, yowzitch_items };
tablespec const *yowzitch = &yowzitch_table;
/* Version and license information.
*/
static char const *vourzhon_items[] = {
"1+*", "1-Tile World: version " VERSION,
"1+", "1-Copyright (c) 2001-2020 by Brian Raiter, Madhav Shanbhag, "
"Eric Schmidt, and Michael Hansen",
"1+", "1-compiled " COMPILE_TIME,
"1+*", "1!This program is free software; you can redistribute it and/or"
" modify it under the terms of the GNU General Public License as"
" published by the Free Software Foundation; either version 2 of"
" the License, or (at your option) any later version.",
"1+*", "1!This program is distributed in the hope that it will be"
" useful, but WITHOUT ANY WARRANTY; without even the implied"
" warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR"
" PURPOSE. See the GNU General Public License for more details.",
"1+*", "1!Bug reports are appreciated, and can be submitted at "
"https://github.com/zrax/tworld/issues."
};
static tablespec const vourzhon_table = { 6, 2, 1, -1, vourzhon_items };
tablespec const *vourzhon = &vourzhon_table;
/* Descriptions of the different surfaces of the levels.
*/
static tiletablerow const help_floors[] = {
{ TRUE, Fire, 0,
"Fire is fatal unless Chip has fire boots." },
{ TRUE, Water, 0,
"Chip drowns in Water without water boots." },
{ TRUE, Ice, 0,
"Chip slides across Ice without ice boots." },
{ TRUE, Slide_East, 0,
"Force floors push Chip along unless he has the force boots." },
{ TRUE, Gravel, 0,
"Gravel is safe to walk on, and no one but Chip can touch it." },
{ TRUE, Dirt, 0,
"Chip is also the only one that can walk on Dirt, but it"
" turns into a normal floor when he steps on it." }
};
/* Descriptions of the various kinds of wall-like obstacles.
*/
static tiletablerow const help_walls[] = {
{ TRUE, Wall_North, Wall,
"Walls can either take up an entire square,"
" or just cut off one direction." },
{ TRUE, BlueWall_Fake, 0,
"Blue Walls can either be real walls, or just mirages. They show"
" their true nature when Chip tries to walk through them." },
{ TRUE, PopupWall, 0,
"Popup Walls spring up when Chip walks across them, blocking retreat." },
{ TRUE, Door_Green, Door_Red,
"Doors can be opened if Chip has a matching key." }
};
/* Descriptions of various objects to be found.
*/
static tiletablerow const help_objects[] = {
{ TRUE, Bomb, 0,
"A Bomb is always fatal to whatever steps on it." },
{ TRUE, CloneMachine, Button_Red,
"Clone Machines produce duplicates of whatever is shown atop them"
" at the touch of a Red Button." },
{ TRUE, Beartrap, Button_Brown,
"A Bear Trap holds fast whatever steps on it. A Brown Button"
" resets the trap and permits escape." },
{ TRUE, Teleport, 0,
"A Teleport instantly transports you to another teleport." },
{ TRUE, SwitchWall_Open, Button_Green,
"Toggle Walls come and go when any Green Button is pressed." },
{ TRUE, Button_Blue, 0,
"A Blue Button causes tanks to turn around." },
{ TRUE, HintButton, 0,
"The Hint Button provides a brief suggestion on how to proceed." },
{ TRUE, Burglar, 0,
"The Thief takes back all your special footgear." }
};
/* Descriptions of things that Chip can use.
*/
static tiletablerow const help_tools[] = {
{ TRUE, ICChip, 0,
"IC Chips are what Chip needs to collect in order to pass through"
" the socket." },
{ TRUE, Key_Green, Key_Yellow,
"Keys permit Chip to open doors of the matching color." },
{ TRUE, Boots_Water, Boots_Fire,
"Boots allow Chip to get past fire and water, and to traverse"
" ice and force floors as if they were normal floors." },
{ TRUE, Block_Static, 0,
"Blocks are obstacles, but they can be pushed around. When pushed into"
" water, the water square turns into dirt." },
{ TRUE, Socket, 0,
"The Socket can only be passed when Chip has acquired"
" the necessary number of IC chips." },
{ TRUE, Exit, 0,
"The Exit takes Chip out. Finding and reaching the Exit"
" is the main goal of every level." }
};
/* Descriptions of the roaming creatures.
*/
static tiletablerow const help_monsters[] = {
{ FALSE, Tank, 0,
"Tanks only move in one direction, until a blue button"
" makes them turn around." },
{ FALSE, Ball, 0,
"Balls bounce back and forth in a straight line." },
{ FALSE, Glider, 0,
"Gliders fly straight until they hit an obstacle,"
" whereupon they turn left." },
{ FALSE, Fireball, 0,
"Fireballs turn to the right upon hitting an obstacle." },
{ FALSE, Walker, 0,
"Walkers turn in a random direction when stopped." },
{ FALSE, Bug, 0,
"Bugs march around things, keeping the wall to their left-hand side." },
{ FALSE, Paramecium, 0,
"Paramecia move along with the wall on their right-hand side." },
{ FALSE, Blob, 0,
"Blobs move about completely at random, albeit slowly." },
{ FALSE, Teeth, 0,
"Finally, Teeth home in on you; like Blobs, they can be outrun." }
};
/* Wrapper function for displaying illustrated help and then waiting
* for a key command.
*/
static int helptilescreen(char const *title, tiletablerow const *table,
int count, int completed)
{
displaytiletable(title, table, count, completed);
return anykey();
}
/* Display the illustrated help sequence for the game.
*/
int gameplayhelp(void)
{
int ret;
ret = helptilescreen("FLOORS", ARRAY(help_floors), +1)
&& helptilescreen("WALLS", ARRAY(help_walls), +1)
&& helptilescreen("OBJECTS", ARRAY(help_objects), +1)
&& helptilescreen("TOOLS", ARRAY(help_tools), +1)
&& helptilescreen("MONSTERS", ARRAY(help_monsters), 0);
cleardisplay();
return ret;
}
/* An input callback used while displaying the list of help topics.
*/
static int scrollinputcallback(int *move)
{
switch (input(TRUE)) {
case CmdPrev10: *move = SCROLL_ALLTHEWAY_UP; break;
case CmdNorth: *move = SCROLL_UP; break;
case CmdPrev: *move = SCROLL_UP; break;
case CmdPrevLevel: *move = SCROLL_UP; break;
case CmdSouth: *move = SCROLL_DN; break;
case CmdNext: *move = SCROLL_DN; break;
case CmdNextLevel: *move = SCROLL_DN; break;
case CmdNext10: *move = SCROLL_ALLTHEWAY_DN; break;
case CmdProceed: *move = TRUE; return FALSE;
case CmdQuitLevel: *move = FALSE; return FALSE;
case CmdQuit: exit(0);
}
return TRUE;
}
/* Display the list of help topics and allow the user to select which
* ones to view.
*/
void onlinemainhelp(int topic)
{
static char const *items[] = {
"2-",
"1+\267", "1-Key commands during the game",
"1+\267", "1-Key commands inbetween games",
"1+\267", "1-Objects of the game",
"1+\267", "1-Command-line options",
"1+\267", "1-About Tile World",
"1+\267", "1-Return to the program"
};
static tablespec const table = { 7, 2, 4, 1, items };
int n;
switch (topic) {
case Help_KeysDuringGame: n = 0; break;
case Help_KeysBetweenGames: n = 1; break;
case Help_ObjectsOfGame: n = 2; break;
case Help_CmdlineOptions: n = 3; break;
case Help_AboutGame: n = 4; break;
default: n = 5; break;
}
while (displaylist("HELP", &table, &n, LIST_HELP, scrollinputcallback)) {
if (n == 5)
break;
switch (n) {
case 0:
displaytable("KEYS - DURING THE GAME",
keyboardhelp(KEYHELP_INGAME), -1);
anykey();
break;
case 1:
displaytable("KEYS - INBETWEEN GAMES",
keyboardhelp(KEYHELP_TWIXTGAMES), -1);
anykey();
break;
case 2:
(void)(helptilescreen("FLOORS", ARRAY(help_floors), +1)
&& helptilescreen("WALLS", ARRAY(help_walls), +1)
&& helptilescreen("OBJECTS", ARRAY(help_objects), +1)
&& helptilescreen("TOOLS", ARRAY(help_tools), +1)
&& helptilescreen("MONSTERS", ARRAY(help_monsters), 0));
break;
case 3:
displaytable("COMMAND-LINE OPTIONS", &yowzitch_table, -1);
anykey();
break;
case 4:
displaytable("ABOUT TILE WORLD", &vourzhon_table, -1);
anykey();
break;
}
}
cleardisplay();
}
/* Display a single online help screen for the given topic.
*/
void onlinecontexthelp(int topic)
{
static char const *firsthelp_items[] = {
"1!Welcome to Tile World!",
"1-",
"1!In order to begin, you must first decide which level set you"
" wish to play. The opening screen shows you the list of all the"
" level sets that are currently available. Use the up and down"
" arrows to move the selection. When the level set of your choice"
" is selected, press Enter to begin.",
"1-",
"1!If the list is long, you may also use the PgUp and PgDn keys to"
" scroll one windowful at a time.",
"1-",
"1!At any point in the program, you may use the Q key to quit the"
" current activity and go back up one step. Typing Shift-Q will"
" exit Tile World completely. Typing ? or F1 at any time will bring"
" up a list of online help topics.",
"1-",
"1!Tile World also comes with offline documentation. Please see the"
" tworld.html file included for more help on playing the game and"
" using this program.",
"1-",
"1!Now, press any key to go back to the list of level sets."
};
static tablespec const firsthelp_table = { 9, 1, 0, 1, firsthelp_items };
switch (topic) {
case Help_First:
displaytable("HELP", &firsthelp_table, -1);
break;
case Help_KeysDuringGame:
displaytable("KEYS - DURING THE GAME",
keyboardhelp(KEYHELP_INGAME), -1);
break;
case Help_KeysBetweenGames:
displaytable("KEYS - INBETWEEN GAMES",
keyboardhelp(KEYHELP_TWIXTGAMES), -1);
break;
case Help_FileListKeys:
displaytable("KEYS - FILE LIST",
keyboardhelp(KEYHELP_FILELIST), -1);
break;
case Help_ScoreListKeys:
displaytable("KEYS - SCORE LIST",
keyboardhelp(KEYHELP_SCORELIST), -1);
break;
}
anykey();
cleardisplay();
}