summaryrefslogtreecommitdiff
path: root/src/main-xxx.c
blob: c8578ced1f231bcf227148928cf6bcce7ab030bf (plain)
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
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
/* File: main-xxx.c */

/* Purpose: Sample visual module for Angband 2.8.1 */

/*
 * This file written by "Ben Harrison (benh@phial.com)".
 *
 * This file is intended to show one way to build a "visual module"
 * for Angband to allow it to work with a new system.  It does not
 * actually work, but if the code near "XXX XXX XXX" comments were
 * replaced with functional code, then it probably would.
 *
 * See "z-term.c" for info on the concept of the "generic terminal",
 * and for more comments about what this file must supply.
 *
 * There are two basic ways to port Angband to a new system.  The
 * first involves modifying the "main-gcu.c" and/or "main-x11.c"
 * files to support some version of "curses" and/or "X11" on your
 * machine, and to compile with the "USE_GCU" and/or "USE_X11"
 * compilation flags defined.  The second involves creating a
 * new "main-xxx.c" file, based on this sample file (or on any
 * existing "main-xxx.c" file), and comes in two flavors, based
 * on whether it contains a "main()" function (as in "main-mac.c"
 * and "main-win.c") or not (as in "main-gcu.c" or "main-x11.c").
 *
 * If the "main-xxx.c" file includes its own "main()" function,
 * then you should NOT link in the "main.c" file, and your "main()"
 * function must process any command line arguments, initialize the
 * "visual system", and call "play_game()" with appropriate arguments.
 *
 * If the "main-xxx.c" file does not include its own "main()"
 * function, then you must add some code to "main.c" which, if
 * the appropriate "USE_XXX" compilation flag is defined, will
 * attempt to call the "init_xxx()" function in the "main-xxx.c"
 * file, which should initialize the "visual system" and return
 * zero if it was successful.  The "main()" function in "main.c"
 * will take care of processing command line arguments and then
 * calling "play_game()" with appropriate arguments.
 *
 * Note that the "util.c" file often contains functions which must
 * be modified in small ways for various platforms, even if you are
 * able to use the existing "main-gcu.c" and/or "main-x11.c" files,
 * in particular, the "file handling" functions may not work on all
 * systems.
 *
 * When you complete a port to a new system, you should email any
 * newly created files, and any changes made to existing files,
 * including "h-config.h", "config.h", and any of the "Makefile"
 * files, to "benh@phial.com" for inclusion in the next version.
 *
 * Try to stick to a "three letter" naming scheme for "main-xxx.c"
 * and "Makefile.xxx" and such for consistency and simplicity.
 */


#include "angband.h"


#ifdef USE_XXX


/*
 * Extra data to associate with each "window"
 *
 * Each "window" is represented by a "term_data" structure, which
 * contains a "term" structure, which contains a pointer (t->data)
 * back to the term_data structure.
 */

typedef struct term_data term_data;

struct term_data
{
	term t;

	/* Other fields if needed XXX XXX XXX */
};



/*
 * Number of "term_data" structures to support XXX XXX XXX
 *
 * You MUST support at least one "term_data" structure, and the
 * game will currently use up to eight "term_data" structures if
 * they are available.
 *
 * If only one "term_data" structure is supported, then a lot of
 * the things that would normally go into a "term_data" structure
 * could be made into global variables instead.
 */
#define MAX_TERM_DATA 1


/*
 * An array of "term_data" structures, one for each "sub-window"
 */
static term_data data[MAX_TERM_DATA];


#if 0	/* Fix the syntax below XXX XXX XXX */

/*
 * The "color" array for the visual module XXX XXX XXX
 *
 * This table should be used in whetever way is necessary to
 * convert the Angband Color Indexes into the proper "color data"
 * for the visual system.  On the Macintosh, these are arrays of
 * three shorts, on the IBM, these are combinations of the eight
 * basic color codes with optional "bright" bits, on X11, these
 * are actual "pixel" codes extracted from another table which
 * contains textual color names.
 *
 * The Angband Color Set (0 to 15):
 *   Black, White, Slate, Orange,    Red, Blue, Green, Umber
 *   D-Gray, L-Gray, Violet, Yellow, L-Red, L-Blue, L-Green, L-Umber
 *
 * Colors 8 to 15 are basically "enhanced" versions of Colors 0 to 7.
 *
 * As decribed in one of the header files, in a perfect world, the
 * colors below should fit a nice clean "quartered" specification
 * in RGB codes, but this must often be Gamma Corrected.  The 1/4
 * parts of each Red,Green,Blue are shown in the comments below,
 * again, these values are *before* gamma correction.
 */
static local_color_data_type color_data[16] =
{
	/* XXX XXX XXX 0,0,0 */, 		/* TERM_DARK */
	/* XXX XXX XXX 4,4,4 */, 		/* TERM_WHITE */
	/* XXX XXX XXX 2,2,2 */, 		/* TERM_SLATE */
	/* XXX XXX XXX 4,2,0 */, 		/* TERM_ORANGE */
	/* XXX XXX XXX 3,0,0 */, 		/* TERM_RED */
	/* XXX XXX XXX 0,2,1 */, 		/* TERM_GREEN */
	/* XXX XXX XXX 0,0,4 */, 		/* TERM_BLUE */
	/* XXX XXX XXX 2,1,0 */, 		/* TERM_UMBER */
	/* XXX XXX XXX 1,1,1 */, 		/* TERM_L_DARK */
	/* XXX XXX XXX 3,3,3 */, 		/* TERM_L_WHITE */
	/* XXX XXX XXX 4,0,4 */, 		/* TERM_VIOLET */
	/* XXX XXX XXX 4,4,0 */, 		/* TERM_YELLOW */
	/* XXX XXX XXX 4,0,0 */, 		/* TERM_L_RED */
	/* XXX XXX XXX 0,4,0 */, 		/* TERM_L_GREEN */
	/* XXX XXX XXX 0,4,4 */, 		/* TERM_L_BLUE */
	/* XXX XXX XXX 3,2,1 */ 		/* TERM_L_UMBER */
};

#endif



/*** Function hooks needed by "Term" ***/


/*
 * Init a new "term"
 *
 * This function should do whatever is necessary to prepare a new "term"
 * for use by the "term.c" package.  This may include clearing the window,
 * preparing the cursor, setting the font/colors, etc.  Usually, this
 * function does nothing, and the "init_xxx()" function does it all.
 */
static void Term_init_xxx(term *t)
{
	term_data *td = (term_data*)(t->data);

	/* XXX XXX XXX */
}



/*
 * Nuke an old "term"
 *
 * This function is called when an old "term" is no longer needed.  It should
 * do whatever is needed to clean up before the program exits, such as wiping
 * the screen, restoring the cursor, fixing the font, etc.  Often this function
 * does nothing and lets the operating system clean up when the program quits.
 */
static void Term_nuke_xxx(term *t)
{
	term_data *td = (term_data*)(t->data);

	/* XXX XXX XXX */
}



/*
 * Do a "special thing" to the current "term"
 *
 * This function must react to a large number of possible arguments, each
 * corresponding to a different "action request" by the "z-term.c" package,
 * or by the application itself.
 *
 * The "action type" is specified by the first argument, which must be a
 * constant of the form "TERM_XTRA_*" as given in "term.h", and the second
 * argument specifies the "information" for that argument, if any, and will
 * vary according to the first argument.
 *
 * In general, this function should return zero if the action is successfully
 * handled, and non-zero if the action is unknown or incorrectly handled.
 */
static errr Term_xtra_xxx(int n, int v)
{
	term_data *td = (term_data*)(Term->data);

	/* Analyze */
	switch (n)
	{
	case TERM_XTRA_EVENT:
		{
			/*
			 * Process some pending events XXX XXX XXX
			 *
			 * Wait for at least one event if "v" is non-zero
			 * otherwise, if no events are ready, return at once.
			 * When "keypress" events are encountered, the "ascii"
			 * value corresponding to the key should be sent to the
			 * "Term_keypress()" function.  Certain "bizarre" keys,
			 * such as function keys or arrow keys, may send special
			 * sequences of characters, such as control-underscore,
			 * plus letters corresponding to modifier keys, plus an
			 * underscore, plus carriage return, which can be used by
			 * the main program for "macro" triggers.  This action
			 * should handle as many events as is efficiently possible
			 * but is only required to handle a single event, and then
			 * only if one is ready or "v" is true.
			 *
			 * This action is required.
			 */

			return (0);
		}

	case TERM_XTRA_FLUSH:
		{
			/*
			 * Flush all pending events XXX XXX XXX
			 *
			 * This action should handle all events waiting on the
			 * queue, optionally discarding all "keypress" events,
			 * since they will be discarded anyway in "z-term.c".
			 *
			 * This action is required, but may not be "essential".
			 */

			return (0);
		}

	case TERM_XTRA_CLEAR:
		{
			/*
			 * Clear the entire window XXX XXX XXX
			 *
			 * This action should clear the entire window, and redraw
			 * any "borders" or other "graphic" aspects of the window.
			 *
			 * This action is required.
			 */

			return (0);
		}

	case TERM_XTRA_SHAPE:
		{
			/*
			 * Set the cursor visibility XXX XXX XXX
			 *
			 * This action should change the visibility of the cursor,
			 * if possible, to the requested value (0=off, 1=on)
			 *
			 * This action is optional, but can improve both the
			 * efficiency (and attractiveness) of the program.
			 */

			return (0);
		}

	case TERM_XTRA_FRESH:
		{
			/*
			 * Flush output XXX XXX XXX
			 *
			 * This action should make sure that all "output" to the
			 * window will actually appear on the window.
			 *
			 * This action is optional, assuming that "Term_text_xxx()"
			 * (and similar functions) draw directly to the screen.
			 */

			return (0);
		}

	case TERM_XTRA_NOISE:
		{
			/*
			 * Make a noise XXX XXX XXX
			 *
			 * This action should produce a "beep" noise.
			 *
			 * This action is optional, but convenient.
			 */

			return (0);
		}

	case TERM_XTRA_BORED:
		{
			/*
			 * Handle random events when bored XXX XXX XXX
			 *
			 * This action is optional, and normally not important
			 */

			return (0);
		}

	case TERM_XTRA_REACT:
		{
			/*
			 * React to global changes XXX XXX XXX
			 *
			 * For example, this action can be used to react to
			 * changes in the global "color_table[256][4]" array.
			 *
			 * This action is optional, but can be very useful for
			 * handling "color changes" and the "arg_sound" and/or
			 * "arg_graphics" options.
			 */

			return (0);
		}

	case TERM_XTRA_ALIVE:
		{
			/*
			 * Change the "hard" level XXX XXX XXX
			 *
			 * This action is used if the program changes "aliveness"
			 * by being either "suspended" (v=0) or "resumed" (v=1)
			 * This action is optional, unless the computer uses the
			 * same "physical screen" for multiple programs, in which
			 * case this action should clean up to let other programs
			 * use the screen, or resume from such a cleaned up state.
			 *
			 * This action is currently only used by "main-gcu.c",
			 * on UNIX machines, to allow proper "suspending".
			 */

			return (0);
		}

	case TERM_XTRA_LEVEL:
		{
			/*
			 * Change the "soft" level XXX XXX XXX
			 *
			 * This action is used when the term window changes "activation"
			 * either by becoming "inactive" (v=0) or "active" (v=1)
			 *
			 * This action can be used to do things like activate the proper
			 * font / drawing mode for the newly active term window.  This
			 * action should NOT change which window has the "focus", which
			 * window is "raised", or anything like that.
			 *
			 * This action is optional if all the other things which depend
			 * on what term is active handle activation themself, or if only
			 * one "term_data" structure is supported by this file.
			 */

			return (0);
		}

	case TERM_XTRA_DELAY:
		{
			/*
			 * Delay for some milliseconds XXX XXX XXX
			 *
			 * This action is useful for proper "timing" of certain
			 * visual effects, such as breath attacks.
			 *
			 * This action is optional, but may be required by this file,
			 * especially if special "macro sequences" must be supported.
			 */

			return (0);
		}

	}

	/* Unknown or Unhandled action */
	return (1);
}


/*
 * Display the cursor
 *
 * This routine should display the cursor at the given location
 * (x,y) in some manner.  On some machines this involves actually
 * moving the physical cursor, on others it involves drawing a fake
 * cursor in some form of graphics mode.  Note the "soft_cursor"
 * flag which tells "z-term.c" to treat the "cursor" as a "visual"
 * thing and not as a "hardware" cursor.
 *
 * You may assume "valid" input if the window is properly sized.
 *
 * You may use the "Term_grab(x, y, &a, &c)" function, if needed,
 * to determine what attr/char should be "under" the new cursor,
 * for "inverting" purposes or whatever.
 */
static errr Term_curs_xxx(int x, int y)
{
	term_data *td = (term_data*)(Term->data);

	/* XXX XXX XXX */

	/* Success */
	return (0);
}


/*
 * Erase some characters
 *
 * This function should erase "n" characters starting at (x,y).
 *
 * You may assume "valid" input if the window is properly sized.
 */
static errr Term_wipe_xxx(int x, int y, int n)
{
	term_data *td = (term_data*)(Term->data);

	/* XXX XXX XXX */

	/* Success */
	return (0);
}


/*
 * Draw some text on the screen
 *
 * This function should actually display an array of characters
 * starting at the given location, using the given "attribute",
 * and using the given string of characters, which contains
 * exactly "n" characters and which is NOT null-terminated.
 *
 * You may assume "valid" input if the window is properly sized.
 *
 * You must be sure that the string, when written, erases anything
 * (including any visual cursor) that used to be where the text is
 * drawn.  On many machines this happens automatically, on others,
 * you must first call "Term_wipe_xxx()" to clear the area.
 *
 * In color environments, you should activate the color contained
 * in "color_data[a & 0x0F]", if needed, before drawing anything.
 *
 * You may ignore the "attribute" if you are only supporting a
 * monochrome environment, since this routine is normally never
 * called to display "black" (invisible) text, including the
 * default "spaces", and all other colors should be drawn in
 * the "normal" color in a monochrome environment.
 *
 * Note that if you have changed the "attr_blank" to something
 * which is not black, then this function must be able to draw
 * the resulting "blank" correctly.
 *
 * Note that this function must correctly handle "black" text if
 * the "always_text" flag is set, if this flag is not set, all the
 * "black" text will be handled by the "Term_wipe_xxx()" hook.
 */
static errr Term_text_xxx(int x, int y, int n, byte a, const char *cp)
{
	term_data *td = (term_data*)(Term->data);

	/* XXX XXX XXX */

	/* Success */
	return (0);
}




/*** Internal Functions ***/


/*
 * Instantiate a "term_data" structure
 *
 * This is one way to prepare the "term_data" structures and to
 * "link" the various informational pieces together.
 *
 * This function assumes that every window should be 80x24 in size
 * (the standard size) and should be able to queue 256 characters.
 * Technically, only the "main screen window" needs to queue any
 * characters, but this method is simple.  One way to allow some
 * variation is to add fields to the "term_data" structure listing
 * parameters for that window, initialize them in the "init_xxx()"
 * function, and then use them in the code below.
 *
 * Note that "activation" calls the "Term_init_xxx()" hook for
 * the "term" structure, if needed.
 */
static void term_data_link(int i)
{
	term_data *td = &data[i];

	/* Initialize the term */
	term_init(td->t, 80, 24, 256);

	/* Choose "soft" or "hard" cursor XXX XXX XXX */
	/* A "soft" cursor must be explicitly "drawn" by the program */
	/* while a "hard" cursor has some "physical" existance and is */
	/* moved whenever text is drawn on the screen.  See "term.c". */
	/* td->t->soft_cursor = TRUE; */

	/* Avoid the "corner" of the window XXX XXX XXX */
	/* td->t->icky_corner = TRUE; */

	/* Use "Term_pict()" for all attr/char pairs XXX XXX XXX */
	/* See the "Term_pict_xxx()" function above. */
	/* td->t->always_pict = TRUE; */

	/* Use "Term_pict()" for some attr/char pairs XXX XXX XXX */
	/* See the "Term_pict_xxx()" function above. */
	/* td->t->higher_pict = TRUE; */

	/* Use "Term_text()" even for "black" text XXX XXX XXX */
	/* See the "Term_text_xxx()" function above. */
	/* td->t->always_text = TRUE; */

	/* Ignore the "TERM_XTRA_BORED" action XXX XXX XXX */
	/* This may make things slightly more efficient. */
	/* td->t->never_bored = TRUE; */

	/* Erase with "white space" XXX XXX XXX */
	/* td->t->attr_blank = TERM_WHITE; */
	/* td->t->char_blank = ' '; */

	/* Prepare the init/nuke hooks */
	td->t->init_hook = Term_init_xxx;
	td->t->nuke_hook = Term_nuke_xxx;

	/* Prepare the template hooks */
	td->t->xtra_hook = Term_xtra_xxx;
	td->t->curs_hook = Term_curs_xxx;
	td->t->wipe_hook = Term_wipe_xxx;
	td->t->text_hook = Term_text_xxx;

	/* Remember where we came from */
	td->t->data = (vptr)(td);

	/* Activate it */
	Term_activate(td->t);

	/* Global pointer */
	ang_term[i] = td->t;
}



/*
 * Initialization function
 */
errr init_xxx(void)
{
	/* Initialize globals XXX XXX XXX */

	/* Initialize "term_data" structures XXX XXX XXX */

	/* Create windows (backwards!) */
	for (i = TERM_DATA_MAX - 1; i >= 0; i--)
	{
		/* Link */
		term_data_link(i);
	}

	/* Success */
	return (0);
}


#ifdef INTERNAL_MAIN


/*
 * Some special machines need their own "main()" function, which they
 * can provide here, making sure NOT to compile the "main.c" file.
 *
 * These systems usually have some form of "event loop", run forever
 * as the last step of "main()", which handles things like menus and
 * window movement, and calls "play_game(FALSE)" to load a game after
 * initializing "savefile" to a filename, or "play_game(TRUE)" to make
 * a new game.  The event loop would also be triggered by "Term_xtra()"
 * (the TERM_XTRA_EVENT action), in which case the event loop would not
 * actually "loop", but would run once and return.
 */


/*
 * An event handler XXX XXX XXX
 *
 * You may need an event handler, which can be used by both
 * by the "TERM_XTRA_BORED" and "TERM_XTRA_EVENT" entries in
 * the "Term_xtra_xxx()" function, and also to wait for the
 * user to perform whatever user-interface operation is needed
 * to request the start of a new game or the loading of an old
 * game, both of which should launch the "play_game()" function.
 */
static bool_ CheckEvents(bool_ wait)
{
	/* XXX XXX XXX */

	return (0);
}


/*
 * Init some stuff
 *
 * This function is used to keep the "path" variable off the stack.
 */
static void init_stuff(void)
{
	char path[1024];

	/* Prepare the path XXX XXX XXX */
	/* This must in some way prepare the "path" variable */
	/* so that it points at the "lib" directory.  Every */
	/* machine handles this in a different way... */
	strcpy(path, "XXX XXX XXX");

	/* Prepare the filepaths */
	init_file_paths(path);
}


/*
 * Main function
 *
 * This function must do a lot of stuff.
 */
int main(int argc, char *argv[])
{
	/* Initialize the machine itself XXX XXX XXX */

	/* Process command line arguments XXX XXX XXX */

	/* Initialize the windows */
	if (init_xxx()) quit("Oops!");

	/* XXX XXX XXX */
	ANGBAND_SYS = "xxx";

	/* Initialize some stuff */
	init_stuff();

	/* Initialize */
	init_angband * /

	/* Allow auto-startup XXX XXX XXX */

	/* Event loop forever XXX XXX XXX */
	while (TRUE) CheckEvents(TRUE);
}


#endif /* INTERNAL_MAIN */


#endif /* USE_XXX */