1 /* File: main-xxx.c */
2
3 /* Purpose: Sample visual module for Angband 2.8.1 */
4
5 /*
6 * This file written by "Ben Harrison (benh@phial.com)".
7 *
8 * This file is intended to show one way to build a "visual module"
9 * for Angband to allow it to work with a new system. It does not
10 * actually work, but if the code near "XXX XXX XXX" comments were
11 * replaced with functional code, then it probably would.
12 *
13 * See "z-term.c" for info on the concept of the "generic terminal",
14 * and for more comments about what this file must supply.
15 *
16 * There are two basic ways to port Angband to a new system. The
17 * first involves modifying the "main-gcu.c" and/or "main-x11.c"
18 * files to support some version of "curses" and/or "X11" on your
19 * machine, and to compile with the "USE_GCU" and/or "USE_X11"
20 * compilation flags defined. The second involves creating a
21 * new "main-xxx.c" file, based on this sample file (or on any
22 * existing "main-xxx.c" file), and comes in two flavors, based
23 * on whether it contains a "main()" function (as in "main-mac.c"
24 * and "main-win.c") or not (as in "main-gcu.c" or "main-x11.c").
25 *
26 * If the "main-xxx.c" file includes its own "main()" function,
27 * then you should NOT link in the "main.c" file, and your "main()"
28 * function must process any command line arguments, initialize the
29 * "visual system", and call "play_game()" with appropriate arguments.
30 *
31 * If the "main-xxx.c" file does not include its own "main()"
32 * function, then you must add some code to "main.c" which, if
33 * the appropriate "USE_XXX" compilation flag is defined, will
34 * attempt to call the "init_xxx()" function in the "main-xxx.c"
35 * file, which should initialize the "visual system" and return
36 * zero if it was successful. The "main()" function in "main.c"
37 * will take care of processing command line arguments and then
38 * calling "play_game()" with appropriate arguments.
39 *
40 * Note that the "util.c" file often contains functions which must
41 * be modified in small ways for various platforms, even if you are
42 * able to use the existing "main-gcu.c" and/or "main-x11.c" files,
43 * in particular, the "file handling" functions may not work on all
44 * systems.
45 *
46 * When you complete a port to a new system, you should email any
47 * newly created files, and any changes made to existing files,
48 * including "h-config.h", "z-config.h", and any of the "Makefile"
49 * files, to "benh@phial.com" for inclusion in the next version.
50 *
51 * Try to stick to a "three letter" naming scheme for "main-xxx.c"
52 * and "Makefile.xxx" and such for consistency and simplicity.
53 */
54
55
56 #include "angband.h"
57
58
59 #ifdef USE_XXX
60
61 cptr help_xxx[] =
62 {
63 "To use XXX",
64 "-f Do something",
65 "-g Do something else",
66 NULL
67 };
68
69 /*
70 * Extra data to associate with each "window"
71 *
72 * Each "window" is represented by a "term_data" structure, which
73 * contains a "term" structure, which contains a pointer (t->data)
74 * back to the term_data structure.
75 */
76
77 typedef struct term_data term_data;
78
79 struct term_data
80 {
81 term t;
82
83 /* Other fields if needed XXX XXX XXX */
84 };
85
86
87
88 /*
89 * Number of "term_data" structures to support XXX XXX XXX
90 *
91 * You MUST support at least one "term_data" structure, and the
92 * game will currently use up to eight "term_data" structures if
93 * they are available.
94 *
95 * If only one "term_data" structure is supported, then a lot of
96 * the things that would normally go into a "term_data" structure
97 * could be made into global variables instead.
98 */
99 #define MAX_TERM_DATA 1
100
101
102 /*
103 * An array of "term_data" structures, one for each "sub-window"
104 */
105 static term_data data[MAX_TERM_DATA];
106
107
108 #if 0 /* Fix the syntax below XXX XXX XXX */
109
110 /*
111 * The "color" array for the visual module XXX XXX XXX
112 *
113 * This table should be used in whetever way is necessary to
114 * convert the Angband Color Indexes into the proper "color data"
115 * for the visual system. On the Macintosh, these are arrays of
116 * three shorts, on the IBM, these are combinations of the eight
117 * basic color codes with optional "bright" bits, on X11, these
118 * are actual "pixel" codes extracted from another table which
119 * contains textual color names.
120 *
121 * The Angband Color Set (0 to 15):
122 * Black, White, Slate, Orange, Red, Blue, Green, Umber
123 * D-Gray, L-Gray, Violet, Yellow, L-Red, L-Blue, L-Green, L-Umber
124 *
125 * Colors 8 to 15 are basically "enhanced" versions of Colors 0 to 7.
126 *
127 * As decribed in one of the header files, in a perfect world, the
128 * colors below should fit a nice clean "quartered" specification
129 * in RGB codes, but this must often be Gamma Corrected. The 1/4
130 * parts of each Red,Green,Blue are shown in the comments below,
131 * again, these values are *before* gamma correction.
132 */
133 static local_color_data_type color_data[16] =
134 {
135 /* XXX XXX XXX 0,0,0 */, /* TERM_DARK */
136 /* XXX XXX XXX 4,4,4 */, /* TERM_WHITE */
137 /* XXX XXX XXX 2,2,2 */, /* TERM_SLATE */
138 /* XXX XXX XXX 4,2,0 */, /* TERM_ORANGE */
139 /* XXX XXX XXX 3,0,0 */, /* TERM_RED */
140 /* XXX XXX XXX 0,2,1 */, /* TERM_GREEN */
141 /* XXX XXX XXX 0,0,4 */, /* TERM_BLUE */
142 /* XXX XXX XXX 2,1,0 */, /* TERM_UMBER */
143 /* XXX XXX XXX 1,1,1 */, /* TERM_L_DARK */
144 /* XXX XXX XXX 3,3,3 */, /* TERM_L_WHITE */
145 /* XXX XXX XXX 4,0,4 */, /* TERM_VIOLET */
146 /* XXX XXX XXX 4,4,0 */, /* TERM_YELLOW */
147 /* XXX XXX XXX 4,0,0 */, /* TERM_L_RED */
148 /* XXX XXX XXX 0,4,0 */, /* TERM_L_GREEN */
149 /* XXX XXX XXX 0,4,4 */, /* TERM_L_BLUE */
150 /* XXX XXX XXX 3,2,1 */ /* TERM_L_UMBER */
151 };
152
153 #endif
154
155
156
157 /*** Function hooks needed by "Term" ***/
158
159
160 /*
161 * Init a new "term"
162 *
163 * This function should do whatever is necessary to prepare a new "term"
164 * for use by the "term.c" package. This may include clearing the window,
165 * preparing the cursor, setting the font/colors, etc. Usually, this
166 * function does nothing, and the "init_xxx()" function does it all.
167 */
Term_init_xxx(term * t)168 static void Term_init_xxx(term *t)
169 {
170 term_data *td = (term_data*)(t->data);
171
172 /* XXX XXX XXX */
173 }
174
175
176
177 /*
178 * Nuke an old "term"
179 *
180 * This function is called when an old "term" is no longer needed. It should
181 * do whatever is needed to clean up before the program exits, such as wiping
182 * the screen, restoring the cursor, fixing the font, etc. Often this function
183 * does nothing and lets the operating system clean up when the program quits.
184 */
Term_nuke_xxx(term * t)185 static void Term_nuke_xxx(term *t)
186 {
187 term_data *td = (term_data*)(t->data);
188
189 /* XXX XXX XXX */
190 }
191
192
193
194 /*
195 * Do a "user action" on the current "term"
196 *
197 * This function allows the visual module to do implementation defined
198 * things when the user activates the "system defined command" command.
199 *
200 * This function is normally not used.
201 *
202 * In general, this function should return zero if the action is successfully
203 * handled, and non-zero if the action is unknown or incorrectly handled.
204 */
Term_user_xxx(int n)205 static errr Term_user_xxx(int n)
206 {
207 term_data *td = (term_data*)(Term->data);
208
209 /* XXX XXX XXX */
210
211 /* Unknown */
212 return (1);
213 }
214
215
216 /*
217 * Do a "special thing" to the current "term"
218 *
219 * This function must react to a large number of possible arguments, each
220 * corresponding to a different "action request" by the "z-term.c" package,
221 * or by the application itself.
222 *
223 * The "action type" is specified by the first argument, which must be a
224 * constant of the form "TERM_XTRA_*" as given in "term.h", and the second
225 * argument specifies the "information" for that argument, if any, and will
226 * vary according to the first argument.
227 *
228 * In general, this function should return zero if the action is successfully
229 * handled, and non-zero if the action is unknown or incorrectly handled.
230 */
Term_xtra_xxx(int n,int v)231 static errr Term_xtra_xxx(int n, int v)
232 {
233 term_data *td = (term_data*)(Term->data);
234
235 /* Analyze */
236 switch (n)
237 {
238 case TERM_XTRA_EVENT:
239 {
240 /*
241 * Process some pending events XXX XXX XXX
242 *
243 * Wait for at least one event if "v" is non-zero
244 * otherwise, if no events are ready, return at once.
245 * When "keypress" events are encountered, the "ascii"
246 * value corresponding to the key should be sent to the
247 * "Term_keypress()" function. Certain "bizarre" keys,
248 * such as function keys or arrow keys, may send special
249 * sequences of characters, such as control-underscore,
250 * plus letters corresponding to modifier keys, plus an
251 * underscore, plus carriage return, which can be used by
252 * the main program for "macro" triggers. This action
253 * should handle as many events as is efficiently possible
254 * but is only required to handle a single event, and then
255 * only if one is ready or "v" is true.
256 *
257 * This action is required.
258 */
259
260 return (0);
261 }
262
263 case TERM_XTRA_FLUSH:
264 {
265 /*
266 * Flush all pending events XXX XXX XXX
267 *
268 * This action should handle all events waiting on the
269 * queue, optionally discarding all "keypress" events,
270 * since they will be discarded anyway in "z-term.c".
271 *
272 * This action is required, but may not be "essential".
273 */
274
275 return (0);
276 }
277
278 case TERM_XTRA_SHAPE:
279 {
280 /*
281 * Set the cursor visibility XXX XXX XXX
282 *
283 * This action should change the visibility of the cursor,
284 * if possible, to the requested value (0=off, 1=on)
285 *
286 * This action is optional, but can improve both the
287 * efficiency (and attractiveness) of the program.
288 */
289
290 return (0);
291 }
292
293 case TERM_XTRA_FROSH:
294 {
295 /*
296 * Flush a row of output XXX XXX XXX
297 *
298 * This action should make sure that row "v" of the "output"
299 * to the window will actually appear on the window.
300 *
301 * This action is optional, assuming that "Term_text_xxx()"
302 * (and similar functions) draw directly to the screen, or
303 * that the "TERM_XTRA_FRESH" entry below takes care of any
304 * necessary flushing issues.
305 */
306
307 return (0);
308 }
309
310 case TERM_XTRA_FRESH:
311 {
312 /*
313 * Flush output XXX XXX XXX
314 *
315 * This action should make sure that all "output" to the
316 * window will actually appear on the window.
317 *
318 * This action is optional, assuming that "Term_text_xxx()"
319 * (and similar functions) draw directly to the screen, or
320 * that the "TERM_XTRA_FROSH" entry above takes care of any
321 * necessary flushing issues.
322 */
323
324 return (0);
325 }
326
327 case TERM_XTRA_NOISE:
328 {
329 /*
330 * Make a noise XXX XXX XXX
331 *
332 * This action should produce a "beep" noise.
333 *
334 * This action is optional, but convenient.
335 */
336
337 return (0);
338 }
339
340 case TERM_XTRA_SOUND:
341 {
342 /*
343 * Make a sound XXX XXX XXX
344 *
345 * This action should produce sound number "v", where the
346 * "name" of that sound is "sound_names[v]". This method
347 * is still under construction.
348 *
349 * This action is optional, and not very important.
350 */
351
352 return (0);
353 }
354
355 case TERM_XTRA_BORED:
356 {
357 /*
358 * Handle random events when bored XXX XXX XXX
359 *
360 * This action is optional, and normally not important
361 */
362
363 return (0);
364 }
365
366 case TERM_XTRA_REACT:
367 {
368 /*
369 * React to global changes XXX XXX XXX
370 *
371 * For example, this action can be used to react to
372 * changes in the global "color_table[256][4]" array.
373 *
374 * This action is optional, but can be very useful for
375 * handling "color changes" and the "arg_sound" and/or
376 * "arg_graphics" options.
377 */
378
379 return (0);
380 }
381
382 case TERM_XTRA_ALIVE:
383 {
384 /*
385 * Change the "hard" level XXX XXX XXX
386 *
387 * This action is used if the program changes "aliveness"
388 * by being either "suspended" (v=0) or "resumed" (v=1)
389 * This action is optional, unless the computer uses the
390 * same "physical screen" for multiple programs, in which
391 * case this action should clean up to let other programs
392 * use the screen, or resume from such a cleaned up state.
393 *
394 * This action is currently only used by "main-gcu.c",
395 * on UNIX machines, to allow proper "suspending".
396 */
397
398 return (0);
399 }
400
401 case TERM_XTRA_LEVEL:
402 {
403 /*
404 * Change the "soft" level XXX XXX XXX
405 *
406 * This action is used when the term window changes "activation"
407 * either by becoming "inactive" (v=0) or "active" (v=1)
408 *
409 * This action can be used to do things like activate the proper
410 * font / drawing mode for the newly active term window. This
411 * action should NOT change which window has the "focus", which
412 * window is "raised", or anything like that.
413 *
414 * This action is optional if all the other things which depend
415 * on what term is active handle activation themself, or if only
416 * one "term_data" structure is supported by this file.
417 */
418
419 return (0);
420 }
421
422 case TERM_XTRA_DELAY:
423 {
424 /*
425 * Delay for some milliseconds XXX XXX XXX
426 *
427 * This action is useful for proper "timing" of certain
428 * visual effects, such as breath attacks.
429 *
430 * This action is optional, but may be required by this file,
431 * especially if special "macro sequences" must be supported.
432 */
433
434 return (0);
435 }
436 }
437
438 /* Unknown or Unhandled action */
439 return (1);
440 }
441
442
443 /*
444 * Display the cursor
445 *
446 * This routine should display the cursor at the given location
447 * (x,y) in some manner. On some machines this involves actually
448 * moving the physical cursor, on others it involves drawing a fake
449 * cursor in some form of graphics mode. Note the "soft_cursor"
450 * flag which tells "z-term.c" to treat the "cursor" as a "visual"
451 * thing and not as a "hardware" cursor.
452 *
453 * You may assume "valid" input if the window is properly sized.
454 *
455 * You may use the "Term_grab(x, y, &a, &c)" function, if needed,
456 * to determine what attr/char should be "under" the new cursor,
457 * for "inverting" purposes or whatever.
458 */
Term_curs_xxx(int x,int y)459 static errr Term_curs_xxx(int x, int y)
460 {
461 term_data *td = (term_data*)(Term->data);
462
463 /* XXX XXX XXX */
464
465 /* Success */
466 return (0);
467 }
468
469
470 /*
471 * Erase some characters
472 *
473 * This function should erase "n" characters starting at (x,y).
474 *
475 * You may assume "valid" input if the window is properly sized.
476 */
Term_wipe_xxx(int x,int y,int n)477 static errr Term_wipe_xxx(int x, int y, int n)
478 {
479 term_data *td = (term_data*)(Term->data);
480
481 /* XXX XXX XXX */
482
483 /* Success */
484 return (0);
485 }
486
487
488 /*
489 * Draw some text on the screen
490 *
491 * This function should actually display an array of characters
492 * starting at the given location, using the given "attribute",
493 * and using the given string of characters, which contains
494 * exactly "n" characters and which is NOT null-terminated.
495 *
496 * You may assume "valid" input if the window is properly sized.
497 *
498 * You must be sure that the string, when written, erases anything
499 * (including any visual cursor) that used to be where the text is
500 * drawn. On many machines this happens automatically, on others,
501 * you must first call "Term_wipe_xxx()" to clear the area.
502 *
503 * In color environments, you should activate the color contained
504 * in "color_data[a & 0x0F]", if needed, before drawing anything.
505 *
506 * You may ignore the "attribute" if you are only supporting a
507 * monochrome environment, since this routine is normally never
508 * called to display "black" (invisible) text, including the
509 * default "spaces", and all other colors should be drawn in
510 * the "normal" color in a monochrome environment.
511 *
512 * Note that if you have changed the "attr_blank" to something
513 * which is not black, then this function must be able to draw
514 * the resulting "blank" correctly.
515 *
516 * Note that this function must correctly handle "black" text if
517 * the "always_text" flag is set, if this flag is not set, all the
518 * "black" text will be handled by the "Term_wipe_xxx()" hook.
519 */
Term_text_xxx(int x,int y,int n,byte a,const char * cp)520 static errr Term_text_xxx(int x, int y, int n, byte a, const char *cp)
521 {
522 term_data *td = (term_data*)(Term->data);
523
524 /* XXX XXX XXX */
525
526 /* Success */
527 return (0);
528 }
529
530
531 /*
532 * Draw some attr/char pairs on the screen
533 *
534 * This routine should display the given "n" attr/char pairs at
535 * the given location (x,y). This function is only used if one
536 * of the flags "always_pict" or "higher_pict" is defined.
537 *
538 * You must be sure that the attr/char pairs, when displayed, will
539 * erase anything (including any visual cursor) that used to be at
540 * the given location. On many machines this is automatic, but on
541 * others, you must first call "Term_wipe_xxx(x, y, 1)".
542 *
543 * With the "higher_pict" flag, this function can be used to allow
544 * the display of "pseudo-graphic" pictures, for example, by using
545 * the attr/char pair as an encoded index into a pixmap of special
546 * "pictures".
547 *
548 * With the "always_pict" flag, this function can be used to force
549 * every attr/char pair to be drawn by this function, which can be
550 * very useful if this file can optimize its own display calls.
551 *
552 * This function is often associated with the "arg_graphics" flag.
553 *
554 * This function is only used if one of the "higher_pict" and/or
555 * "always_pict" flags are set.
556 */
Term_pict_xxx(int x,int y,int n,const byte * ap,const char * cp,const byte * tap,const char * tcp)557 static errr Term_pict_xxx(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp)
558 {
559 term_data *td = (term_data*)(Term->data);
560
561 /* XXX XXX XXX */
562
563 /* Success */
564 return (0);
565 }
566
567
568
569 /*** Internal Functions ***/
570
571
572 /*
573 * Instantiate a "term_data" structure
574 *
575 * This is one way to prepare the "term_data" structures and to
576 * "link" the various informational pieces together.
577 *
578 * This function assumes that every window should be 80x24 in size
579 * (the standard size) and should be able to queue 256 characters.
580 * Technically, only the "main screen window" needs to queue any
581 * characters, but this method is simple. One way to allow some
582 * variation is to add fields to the "term_data" structure listing
583 * parameters for that window, initialize them in the "init_xxx()"
584 * function, and then use them in the code below.
585 *
586 * Note that "activation" calls the "Term_init_xxx()" hook for
587 * the "term" structure, if needed.
588 */
term_data_link(int i)589 static void term_data_link(int i)
590 {
591 term_data *td = &data[i];
592
593 /* Initialize the term */
594 term_init(td->t, 80, 24, 256);
595
596 /* Choose "soft" or "hard" cursor XXX XXX XXX */
597 /* A "soft" cursor must be explicitly "drawn" by the program */
598 /* while a "hard" cursor has some "physical" existance and is */
599 /* moved whenever text is drawn on the screen. See "term.c". */
600 /* td->t->soft_cursor = TRUE; */
601
602 /* Avoid the "corner" of the window XXX XXX XXX */
603 /* td->t->icky_corner = TRUE; */
604
605 /* Use "Term_pict()" for all attr/char pairs XXX XXX XXX */
606 /* See the "Term_pict_xxx()" function above. */
607 /* td->t->always_pict = TRUE; */
608
609 /* Use "Term_pict()" for some attr/char pairs XXX XXX XXX */
610 /* See the "Term_pict_xxx()" function above. */
611 /* td->t->higher_pict = TRUE; */
612
613 /* Use "Term_text()" even for "black" text XXX XXX XXX */
614 /* See the "Term_text_xxx()" function above. */
615 /* td->t->always_text = TRUE; */
616
617 /* Ignore the "TERM_XTRA_BORED" action XXX XXX XXX */
618 /* This may make things slightly more efficient. */
619 /* td->t->never_bored = TRUE; */
620
621 /* Ignore the "TERM_XTRA_FROSH" action XXX XXX XXX */
622 /* This may make things slightly more efficient. */
623 /* td->t->never_frosh = TRUE; */
624
625 /* Erase with "white space" (use if don't have Term_wipe_xxx) XXX XXX XXX */
626 /* td->t->attr_blank = TERM_WHITE; */
627 /* td->t->char_blank = ' '; */
628
629 /* Prepare the init/nuke hooks */
630 td->t->init_hook = Term_init_xxx;
631 td->t->nuke_hook = Term_nuke_xxx;
632
633 /* Prepare the template hooks */
634 td->t->user_hook = Term_user_xxx;
635 td->t->xtra_hook = Term_xtra_xxx;
636 td->t->curs_hook = Term_curs_xxx;
637 td->t->wipe_hook = Term_wipe_xxx;
638 td->t->text_hook = Term_text_xxx;
639 td->t->pict_hook = Term_pict_xxx;
640
641 /* Remember where we came from */
642 td->t->data = (vptr)(td);
643
644 /* Activate it */
645 Term_activate(td->t);
646
647 /* Global pointer */
648 ang_term[i] = td->t;
649 }
650
651
652
653 /*
654 * Initialization function
655 */
init_xxx(void)656 errr init_xxx(void)
657 {
658 /* Initialize globals XXX XXX XXX */
659
660 /* Initialize "term_data" structures XXX XXX XXX */
661
662 /* Create windows (backwards!) */
663 for (i = TERM_DATA_MAX - 1; i >= 0; i--)
664 {
665 /* Link */
666 term_data_link(i);
667 }
668
669 /* Success */
670 return (0);
671 }
672
673
674 #ifdef INTERNAL_MAIN
675
676
677 /*
678 * Some special machines need their own "main()" function, which they
679 * can provide here, making sure NOT to compile the "main.c" file.
680 *
681 * These systems usually have some form of "event loop", run forever
682 * as the last step of "main()", which handles things like menus and
683 * window movement, and calls "play_game(FALSE)" to load a game after
684 * initializing "savefile" to a filename, or "play_game(TRUE)" to make
685 * a new game. The event loop would also be triggered by "Term_xtra()"
686 * (the TERM_XTRA_EVENT action), in which case the event loop would not
687 * actually "loop", but would run once and return.
688 */
689
690
691 /*
692 * An event handler XXX XXX XXX
693 *
694 * You may need an event handler, which can be used by both
695 * by the "TERM_XTRA_BORED" and "TERM_XTRA_EVENT" entries in
696 * the "Term_xtra_xxx()" function, and also to wait for the
697 * user to perform whatever user-interface operation is needed
698 * to request the start of a new game or the loading of an old
699 * game, both of which should launch the "play_game()" function.
700 */
CheckEvents(bool wait)701 static bool CheckEvents(bool wait)
702 {
703 /* XXX XXX XXX */
704
705 return (0);
706 }
707
708
709 /*
710 * Init some stuff
711 *
712 * This function is used to keep the "path" variable off the stack.
713 */
init_stuff(void)714 static void init_stuff(void)
715 {
716 char path[1024];
717
718 /* Prepare the path XXX XXX XXX */
719 /* This must in some way prepare the "path" variable */
720 /* so that it points at the "lib" directory. Every */
721 /* machine handles this in a different way... */
722 strcpy(path, "XXX XXX XXX");
723
724 /* Prepare the filepaths */
725 init_file_paths(path);
726 }
727
728
729 /*
730 * Main function
731 *
732 * This function must do a lot of stuff.
733 */
main(int argc,char * argv[])734 int main(int argc, char *argv[])
735 {
736 /* Initialize the machine itself XXX XXX XXX */
737
738 /* Process command line arguments XXX XXX XXX */
739
740 /* Initialize the windows */
741 if (init_xxx()) quit("Oops!");
742
743 /* XXX XXX XXX */
744 ANGBAND_SYS = "xxx";
745
746 /* Initialize some stuff */
747 init_stuff();
748
749 /* Initialize */
750 init_angband */
751
752 /* Allow auto-startup XXX XXX XXX */
753
754 /* Event loop forever XXX XXX XXX */
755 while (TRUE) CheckEvents(TRUE);
756 }
757
758
759 #endif /* INTERNAL_MAIN */
760
761
762 #endif /* USE_XXX */
763