1 /*
2 	swinit	 -	SW initialization
3 
4 	Copyright (C) 1984-2003 David L. Clark.
5 	This program is free software; you can redistribute it and/or modify it under
6 	the terms of the GNU General Public License as published by the Free Software
7 	Foundation; either version 2 of the License, or (at your option) any later
8 	version. This program is distributed in the hope that it will be useful,
9 	but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 	or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 	more details. You should have received a copy of the GNU General Public
12 	License along with this program; if not, write to the Free Software Foundation,
13 	Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
14 
15 	Modification History:
16 			84-02-02	Development
17 			85-10-31	Atari
18 			87-01-09	BMB standard help text.
19 					Multiple serial ports.
20 			87-03-09	Microsoft compiler.
21 			87-03-11	Smaller fuel tank explosions.
22 			87-03-12	Wounded airplanes.
23 			87-03-30	Novice player.
24 			87-03-31	Missiles
25 			87-03-31	Less x-movement in explosions
26 			87-04-04	Missile and starburst support
27 			87-04-05	Less x-movement in explosions
28 			87-04-06	Computer plane avoiding oxen.
29 			87-04-09	Fix to initial missile path.
30 					Delay between starbursts
31 			96-12-26	New network version.
32 					Remove keyboard prompts.
33 					Speed up game a bit.
34 			99-01-24	1999 copyright.
35 					Disable network support.
36 			2000-10-29	Copyright update.
37 					Comment out multiplayer selection
38 					  on startup.
39 			2003-01-27	GNU General Public License.
40 			2003-02-04  GNU public license in -?
41 */
42 #include	"sw.h"
43 
44 
45 extern	int	_systype;		/* operating environment	    */
46 extern	int	playmode;		/* Mode of play 		    */
47 extern	GAMES	swgames[], *currgame;	/* Game parameters and current game */
48 extern	GRNDTYPE ground[];		/* Ground height by pixel	    */
49 extern	GRNDTYPE orground[];		/* Original ground height by pixel  */
50 
51 
52 extern	MULTIO	*multbuff;		/* Communications buffer	    */
53 
54 extern	BOOL	hires;			/* High res flag		    */
55 extern	BOOL	titleflg;		/* Title flag			    */
56 extern	BOOL	disppos;		/* Display position flag	    */
57 extern	int	keydelay;		/*  Number of displays per keystroke*/
58 extern	int	soundflg;		/*  Sound flag			    */
59 extern	BOOL	repflag;		/*  Report statistics flag	    */
60 extern	BOOL	joystick;		/*  Joy stick being used	    */
61 extern	BOOL	ibmkeybd;		/*  IBM keyboard or look-alike	    */
62 extern	int	multtick;		/*  Multiple user tick delay	    */
63 extern	BOOL	inplay; 		/*  Currently playing flag	    */
64 extern	int	koveride;		/* Keyboard override index number   */
65 extern	int	missok; 		/* Missiles supported		    */
66 
67 extern	int	gamenum;		/* Current game number		    */
68 extern	int	gmaxspeed, gminspeed;	/* Speed range based on game number */
69 extern	int	targrnge;		/* Target range based on game number*/
70 
71 extern	int	displx, disprx; 	/* Display left and right	    */
72 extern	char	auxdisp[];		/* Auxiliary display area	    */
73 extern	BOOL	dispinit;		/* Initalized display flag.	    */
74 extern	char	*histin, *histout;	/* History input and output files   */
75 
76 extern	OBJECTS *nobjects;		/* Objects list.		    */
77 extern	OBJECTS oobjects[];		/* Original plane object description*/
78 extern	OBJECTS *objbot, *objtop,	/* Top and bottom of object list    */
79 		*objfree,		/* Free list			    */
80 		*deltop, *delbot;	/* Newly deallocated objects	    */
81 extern	OBJECTS *targets[];		/* Target status array		    */
82 extern	int	numtarg[];		/* number of active targets	    */
83 extern	OBJECTS topobj, botobj; 	/* Top and Bottom of object by x lst*/
84 extern	int	player; 		/* Pointer to player's object       */
85 extern	BOOL	plyrplane;		/* Current object is the player     */
86 extern	BOOL	compplane;		/* Current object is a comp plane   */
87 extern	int	currobx;		/* Current object index 	    */
88 extern	OLDWDISP wdisp[];		/* World display status 	    */
89 extern	int	splatox;		/* Display splatted ox		    */
90 extern	int	oxsplatted;		/* An ox has been splotted	    */
91 extern	int	movetick, movemax;	/* Move timing			    */
92 
93 extern	int	dispcomp(),		/*  Display and move functions	    */
94 		movecomp(),
95 		dispplyr(),
96 		moveplyr(),
97 		moveshot(),
98 		dispbomb(),
99 		movebomb(),
100 		movetarg(),
101 		disptarg(),
102 		moveexpl(),
103 		dispexpl(),
104 		movesmok(),
105 		movebird(),
106 		dispbird(),
107 		moveflck(),
108 		dispflck(),
109 		moveox(),
110 		movemiss(),
111 		dispmiss(),
112 		moveburst(),
113 		dispburst();
114 
115 extern	OBJECTS *allocobj();
116 
117 extern	int	 swbreak(), swtick(), swshfprt(), swkeyint();
118 extern	int	 counttick, countmove;	 /* Performance counters   */
119 
120 
121 extern	int	sintab[];		/*  sine table based on angles	  */
122 
123 extern	jmp_buf envrestart;		/* Restart environment for restart  */
124 					/*  long jump.			    */
125 
126 extern	int	endsts[];		/* End of game status and move count*/
127 extern	int	endcount;
128 extern	BOOL	goingsun;		/* Heading for the sun flag	    */
129 extern	OBJECTS *compnear[];		/*  Array of planes near computers*/
130 extern	unsigned explseed;		/* explosion seed		  */
131 
132 extern	char	*multfile;		/* Multi user files		  */
133 extern	char	*cmndfile;
134 extern	unsigned multaddr;		/* Multiple user diskette adapter */
135 					/*   address			  */
136 
137 extern	int	 maxcrash;		/* Maximum number of crashes	  */
138 
139 extern	int	 ctlbflag;		/* Control break has been pressed */
140 
141 static	int	 savescore;		/* save players score on restart  */
142 static	BOOL	 ghost; 		/* ghost display flag		  */
143 
144 static	char	 *helptxt[] = { 	/* Help text			  */
145 "",
146 "SOPWITH, (The Author's Edition)",
147 "(c) Copyright 1984-2003 David L. Clark",
148 "Modification Date:  February 4, 2003",
149 "",
150 "This program is free software; you can redistribute it and/or modify it under",
151 "the terms of the GNU General Public License as published by the Free Software",
152 "Foundation; either version 2 of the License, or (at your option) any later",
153 "version. This program is distributed in the hope that it will be useful,",
154 "but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY",
155 "or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for",
156 "more details. You should have received a copy of the GNU General Public",
157 "License along with this program; if not, write to the Free Software Foundation,",
158 "Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.", 
159 "",
160 "Usage:  sopwith [options]",
161 "The options are:",
162 "        -n :  novice single player",
163 "        -s :  single player",
164 "        -c :  single player against computer",
165 /*
166 "        -m :  multiple players on a network",
167 */
168 "        -a :  2 players over asynchrounous communications line",
169 "              (Only one of -n, -s, -c, -a may be specified)",
170 "        -k :  keyboard only",
171 "        -j :  joystick and keyboard",
172 "              (Only one of -k and -j  may be specified)",
173 /*
174 "        -i :  IBM PC keyboard",
175 */
176 "        -q :  begin game with sound off",
177 /*
178 "        -r :  resets the multiuser communications file after an abnormal",
179 "                  end of a game",
180 "        -d*:  overrides the default drive C as the device containing the",
181 "                  communications file",
182 */
183 "        -p#:  overrides asynchronous port 1 as the asynchrounous port",
184 "                  to use",
185 0
186 };
187 
188 
189 
190 swinit( argc, argv )
191 int	argc;
192 char	*argv[];
193 {
194 BOOL	reset = FALSE;
195 BOOL	n = FALSE;
196 BOOL	s = FALSE;
197 BOOL	c = FALSE;
198 BOOL	m = FALSE;
199 BOOL	a = FALSE;
200 BOOL	k = FALSE;
201 int	modeset, keyset;
202 char	*device   = "\0              ";
203 
204 
205 	if ( getflags( &argc, &argv,
206 			/*---- 96/12/27------
207 			"n&s&c&m&a&k&i&j&q&h*v*r&d*f*n*t#w&y#e&g#x&:",
208 			&n, &s, &c, &m, &a, &k, &ibmkeybd, &joystick, &soundflg,
209 			&histout, &histin, &reset, &device,
210 			&multfile, &cmndfile, &multtick, &hires, &keydelay,
211 			&repflag, &gamenum, &missok )
212 			------ 96/12/27----*/
213 			/*---- 99/01/24------
214 			"n&s&c&m&a&k&j&q&h*v*r&d*f*t#w&y#e&g#x&:",
215 			&n, &s, &c, &m, &a, &k, &joystick, &soundflg,
216 			&histout, &histin, &reset, &device,
217 			&multfile, &multtick, &hires, &keydelay,
218 			&repflag, &gamenum, &missok )
219 			------ 99/01/24----*/
220 			"n&s&c&a&k&j&q&x&:",
221 			&n, &s, &c, &a, &k, &joystick, &soundflg,
222 			&missok )
223 		|| ( ( modeset = n + s + c + m + a ) > 1 )
224 		|| ( ( keyset = joystick + k ) > 1 ) ) {
225 		disphelp( helptxt );
226 		exit( 1 );
227 	}
228 
229 	soundflg = !soundflg;
230 	if ( modeset && keyset )
231 		titleflg = TRUE;
232 
233 	movemax=15;
234 	initseed();
235 	explseed = histinit( explseed );
236 	initsndt();
237 	intsoff();
238 	_intsetup( BREAKINT, swbreak, csseg(), dsseg() );
239 	_intsetup( CLOCKINT, swtick, csseg(), dsseg() );
240 	initgrnd();
241 	swtitln();
242 	intson();
243 
244 	if ( modeset )
245 		playmode = n ? NOVICE
246 			     : ( s ? SINGLE
247 			     : ( c ? COMPUTER
248 			     : ( m ? MULTIPLE : ASYNCH ) ) );
249 	else
250 		getmode();
251 
252 	if ( !keyset )
253 		getkey();
254 
255 	if ( ( playmode == MULTIPLE ) || ( playmode == ASYNCH ) ) {
256 		maxcrash = MAXCRASH * 2;
257 		if ( playmode == MULTIPLE )
258 			init1mul( reset, device );
259 		else
260 			init1asy();
261 		initgrnd();
262 		initobjs();
263 		if ( playmode == MULTIPLE )
264 			init2mul();
265 		else
266 			init2asy();
267 		inittarg();
268 		if ( currgame->gm_specf )
269 			( *currgame->gm_specf ) ();
270 		initdisp( NO );
271 		if ( keydelay == -1 )
272 			keydelay = 1;
273 	} else {
274 		if ( keydelay == -1 )
275 			keydelay = 1;
276 		maxcrash = MAXCRASH;
277 		currgame = &swgames[0];
278 		clrprmpt();
279 		initobjs();
280 		initplyr( NULL );
281 		initcomp( NULL );
282 		initcomp( NULL );
283 		initcomp( NULL );
284 		inittarg();
285 		if ( currgame->gm_specf )
286 			( *currgame->gm_specf ) ();
287 		initdisp( NO );
288 	}
289 
290 	initflck();
291 	initoxen();
292 
293 	initgdep();
294 
295 	intsoff();
296 	_intsetup( PRINTINT, swshfprt, csseg(), dsseg() );
297 	koveride = _intsetup( KEYINT, swkeyint, csseg(), dsseg() );
298 	inplay = TRUE;
299 	intson();
300 }
301 
302 
303 
304 static	disphelp( hp )
305 char	**hp;
306 {
307 register char	**h;
308 
309 	h = hp;
310 	puts( "\r\n" );
311 	while ( *h ) {
312 		puts( *h++ );
313 		puts( "\r\n" );
314 	}
315 }
316 
317 
318 
319 
320 
321 initseed()
322 {
323 #ifdef IBMPC
324 	while ( !explseed ) {
325 		outportb( 0x43, 0 );
326 		explseed = ( 0x00FF & inportb( 0x40 ) )
327 			 | ( 0xFF00 & ( inportb( 0x40 ) << 8 ) );
328 	}
329 #endif
330 #ifdef ATARI
331 long	trap14();
332 
333 	explseed = trap14( 17 );
334 #endif
335 }
336 
337 
338 
339 
340 
341 swrestart()
342 {
343 register OBJECTS  *ob;
344 register int	  tickwait, inc;
345 
346 	if ( endsts[player] == WINNER ) {
347 		ob = &nobjects[player];
348 		inc = 0;
349 		while ( ob->ob_crashcnt++ < maxcrash ) {
350 			ob->ob_score += ( inc += 25 );
351 			setvdisp();
352 			dispcgge( ob );
353 			dispscore( ob );
354 			intsoff();
355 			tickwait = 5;
356 			counttick = 0;
357 			intson();
358 			while ( counttick < tickwait );
359 		}
360 		++gamenum;
361 		savescore = ob->ob_score;
362 	} else {
363 		gamenum = 0;
364 		savescore = 0;
365 	}
366 
367 	initsndt();
368 	initgrnd();
369 	initobjs();
370 	initplyr( NULL );
371 	initcomp( NULL );
372 	initcomp( NULL );
373 	initcomp( NULL );
374 	inittarg();
375 	if ( currgame->gm_specf )
376 		( *currgame->gm_specf ) ();
377 
378 	initdisp( NO );
379 	initflck();
380 	initoxen();
381 	initgdep();
382 
383 	longjmp( envrestart, 0 );
384 }
385 
386 
387 
388 initgdep()
389 {
390 
391 	gmaxspeed = MAX_SPEED + gamenum;
392 	gminspeed = MIN_SPEED + gamenum;
393 
394 	targrnge = 150;
395 	if ( gamenum < 6 )
396 		targrnge -= 15 * ( 6 - gamenum );
397 	targrnge *= targrnge;
398 }
399 
400 
401 
402 
403 
404 
405 clrprmpt()
406 {
407 #ifdef	IBMPC
408 register int	i;
409 struct	regval	reg;
410 
411 	for ( i = 0; i < 4; ++i ) {
412 		swposcur( 0, 20 + i );
413 		reg.axr = 0x0A20;
414 		reg.bxr = 0;
415 		reg.cxr = hires ? 80 : 40;
416 		sysint( 0x10, &reg, &reg );
417 	}
418 	swposcur( 0, 20 );
419 #endif
420 
421 #ifdef	ATARI
422 register int	 i;
423 
424 	for ( i = 0; i < 4; ++i ) {
425 		swposcur( 0, 20 + i );
426 		puts( "\33K" );
427 	}
428 	swposcur( 0, 20 );
429 #endif
430 }
431 
432 
433 
434 
435 static getkey()
436 {
437 register char	 key;
438 
439 	/*----------------97/12/27--------------
440 	clrprmpt();
441 	puts( "Key: 1 - Joystick with IBM Keyboard\r\n" );
442 	puts( "     2 - Joystick with non-IBM Keyboard\r\n" );
443 	puts( "     3 - IBM Keyboard only\r\n" );
444 	puts( "     4 - Non-IBM keyboard only\r\n" );
445 	FOREVER {
446 		if ( ctlbreak() )
447 			swend( NULL, NO );
448 		if ( ( ( key = swgetc() & 0x00FF ) < '1' )
449 			|| ( key > '4' ) )
450 			continue;
451 		joystick = ( key <= '2' );
452 		ibmkeybd = ( key == '1' ) || ( key == '3' );
453 		return;
454 	}
455 	------------------97/12/27--------------*/
456 	clrprmpt();
457 	puts( "Key: K - Keyboard Only\r\n" );
458 	puts( "     J - Joystick and Keyboard\r\n" );
459 	FOREVER {
460 		if ( ctlbreak() )
461 			swend( NULL, NO );
462 		if ( ( ( key = toupper(swgetc() & 0x00FF) ) != 'K' )
463 			&& ( key != 'J' ) )
464 			continue;
465 		joystick = key == 'J';
466 		ibmkeybd = 1;
467 		return;
468 	}
469 }
470 
471 
472 
473 
474 
475 static getmode()
476 {
477 	clrprmpt();
478 	puts( "Key: S - single player\r\n" );
479 	puts( "     C - single player against computer\r\n" );
480 	if ( _systype == PCDOS ) {
481 		/*--------------- 2000/10/29 -----------------------
482 		puts( "     M - multiple players on network\r\n" );
483 		----------------- 2000/10/29 ---------------------*/
484 		puts( "     A - 2 players on asynchronous line" );
485 	}
486 	FOREVER {
487 		if ( ctlbreak() )
488 			swend( NULL, NO );
489 		switch ( toupper( swgetc() & 0x00FF ) ) {
490 			case 'S':
491 				clrprmpt();
492 				puts( "Key: N - novice player\r\n" );
493 				puts( "     E - expert player\r\n" );
494 				FOREVER {
495 					if ( ctlbreak() )
496 						swend( NULL, NO );
497 					switch ( toupper( swgetc()
498 							& 0x00FF ) ){
499 						case 'N':
500 							playmode = NOVICE;
501 							return;
502 						case 'E':
503 							playmode = SINGLE;
504 							return;
505 					}
506 				}
507 			case 'M':
508 				/*----- 2000/10/29 ----------
509 				if ( _systype == PCDOS ) {
510 					playmode = MULTIPLE;
511 					return;
512 				}
513 				------- 2000/10/29 --------*/
514 				break;
515 			case 'C':
516 				playmode = COMPUTER;
517 				return;
518 			case 'A':
519 				if ( _systype == PCDOS ) {
520 					playmode = ASYNCH;
521 					return;
522 				}
523 				break;
524 			default:
525 				break;
526 		}
527 	}
528 }
529 
530 
531 
532 
533 getgame()
534 {
535 register int	 game;
536 
537 	clrprmpt();
538 	puts( "         Key a game number" );
539 	FOREVER {
540 		if ( ctlbreak() )
541 			swend( NULL, NO );
542 		if ( ( ( game = ( swgetc() & 0x00FF ) - '0' ) >= 0 )
543 		    && ( game <= MAX_GAME ) )
544 			return( game );
545 	}
546 }
547 
548 
549 
550 
551 BOOL	ctlbreak()
552 {
553 	return( ctlbflag );
554 }
555 
556 
557 
558 
559 static	initgrnd()
560 {
561 	movmem( orground, ground, sizeof( GRNDTYPE ) * MAX_X );
562 }
563 
564 
565 
566 
567 initdisp( reset )
568 BOOL	reset;
569 {
570 register OBJECTS *ob;
571 OBJECTS 	 ghostob;
572 extern	 char	 swghtsym[];
573 
574 	splatox = oxsplatted = 0;
575 	if ( !reset ) {
576 		clrdispa();
577 		setadisp();
578 		dispworld();
579 		swtitlf();
580 		ghost = FALSE;
581 	}
582 	movedisp();
583 	setvdisp();
584 	initwobj();
585 	initscore();
586 
587 	ob = &nobjects[player];
588 	if ( ghost ) {
589 		ghostob.ob_type = DUMMYTYPE;
590 		ghostob.ob_symhgt = ghostob.ob_symwdt = 8;
591 		ghostob.ob_clr = ob->ob_clr;
592 		ghostob.ob_newsym = swghtsym;
593 		swputsym( GHOSTX, 12, &ghostob );
594 	} else {
595 		dispfgge( ob );
596 		dispbgge( ob );
597 		dispmgge( ob );
598 		dispsbgge( ob );
599 		dispsgge( ob );
600 		dispcgge( ob );
601 	}
602 	dispinit = TRUE;
603 }
604 
605 
606 
607 static	initscore()
608 {
609 	if ( savescore ) {
610 		  nobjects[0].ob_score = savescore;
611 		  savescore = 0;
612 	}
613 
614 	dispscore( &nobjects[0] );
615 	if ( ( ( playmode == MULTIPLE ) || ( playmode == ASYNCH ) )
616 		&& ( multbuff->mu_maxplyr > 1 ) )
617 		dispscore( &nobjects[1] );
618 }
619 
620 
621 
622 
623 dispcgge( ob )
624 OBJECTS *ob;
625 {
626 	dispgge( CGUAGEX, maxcrash - ob->ob_crashcnt, maxcrash, ob->ob_clr );
627 }
628 
629 
630 
631 
632 dispfgge( ob )
633 OBJECTS *ob;
634 {
635 	dispgge( FGUAGEX, ob->ob_life >> 4, MAXFUEL >> 4, ob->ob_clr );
636 }
637 
638 
639 
640 
641 dispbgge( ob )
642 OBJECTS *ob;
643 {
644 	dispgge( BGUAGEX, ob->ob_bombs, MAXBOMBS, 3 - ob->ob_clr );
645 }
646 
647 
648 
649 
650 dispsgge( ob )
651 OBJECTS *ob;
652 {
653 	dispgge( SGUAGEX, ob->ob_rounds, MAXROUNDS, 3 );
654 }
655 
656 
657 
658 
659 dispmgge( ob )
660 OBJECTS *ob;
661 {
662 	dispgge( MGUAGEX, ob->ob_missiles, MAXMISSILES, ob->ob_clr );
663 }
664 
665 
666 
667 
668 dispsbgge( ob )
669 OBJECTS *ob;
670 {
671 	dispgge( SBGUAGEX, ob->ob_bursts, MAXBURSTS, 3 - ob->ob_clr );
672 }
673 
674 
675 
676 
677 static	dispgge( x, cury, maxy, clr )
678 int	x, cury, maxy, clr;
679 {
680 register int	 y;
681 
682 	if ( ghost )
683 		return;
684 
685 	cury = cury * 10 / maxy - 1;
686 	if ( cury > 9 )
687 		cury = 9;
688 	for ( y = 0; y <= cury; ++y )
689 		swpntsym( x, y, clr );
690 	for ( ; y <= 9; ++y )
691 		swpntsym( x, y, 0 );
692 }
693 
694 
695 
696 static dispworld()
697 {
698 register int	 x, y, dx, maxh, sx;
699 
700 	dx = 0;
701 	sx = SCR_CENTR;
702 
703 	maxh = 0;
704 	y = 0;
705 	for ( x = 0; x < MAX_X; ++x ) {
706 
707 		if ( ground[x] > maxh )
708 			maxh = ground[x];
709 
710 		if ( ( ++dx ) == WRLD_RSX ) {
711 			maxh /= WRLD_RSY;
712 			if ( maxh == y )
713 				swpntsym( sx, maxh, 7 );
714 			else
715 				if ( maxh > y )
716 					for ( ++y; y <= maxh; ++y )
717 						swpntsym( sx, y, 7 );
718 				else
719 					for ( --y; y >= maxh; --y )
720 						swpntsym( sx, y, 7 );
721 			y = maxh;
722 			swpntsym( sx, 0, 11 );
723 			++sx;
724 			dx = maxh = 0;
725 		}
726 	}
727 	maxh = MAX_Y / WRLD_RSY;
728 	for ( y = 0; y <= maxh; ++y ) {
729 		swpntsym( SCR_CENTR, y, 11 );
730 		swpntsym( sx, y, 11 );
731 	}
732 
733 	for ( x = 0; x < SCR_WDTH; ++x )
734 		swpntsym( x, (SCR_MNSH+2), 7 );
735 }
736 
737 
738 
739 
740 
741 static initwobj()
742 {
743 int	x;
744 register OBJECTS *ob;
745 register OLDWDISP *ow;
746 
747 	ow = wdisp;
748 	ob = nobjects;
749 	for ( x = 0; x < MAX_OBJS; ++x, ow++, ob++ )
750 		ow->ow_xorplot = ob->ob_drwflg = ob->ob_delflg = 0;
751 
752 	for ( x = 0; x < MAX_TARG; ++x )
753 		if ( ( ob = targets[x] ) && ( ob->ob_state != FINISHED ) )
754 			dispwobj( ob );
755 
756 }
757 
758 
759 
760 static movedisp()
761 {
762 #ifdef IBMPC
763 	swsetblk( 0,	    SCR_SEGM, 0x1000, 0 );
764 	swsetblk( SCR_ROFF, SCR_SEGM, 0x1000, 0 );
765 	movblock( auxdisp,	    dsseg(), 0x1000, SCR_SEGM, 0x1000 );
766 	movblock( auxdisp + 0x1000, dsseg(), 0x3000, SCR_SEGM, 0x1000 );
767 #endif
768 
769 #ifdef ATARI
770 long	trap14(), vidram;
771 
772 	vidram = trap14( 3 );
773 	setmem( vidram, 0x4000, 0 );
774 	movmem( auxdisp, vidram + 0x4000, 0x4000 );
775 #endif
776 }
777 
778 
779 
780 
781 static clrdispa()
782 {
783 #ifdef	IBMPC
784 	setmem( auxdisp, 0x2000, 0 );
785 #endif
786 
787 #ifdef	ATARI
788 	setmem( auxdisp, 0x4000, 0 );
789 #endif
790 }
791 
792 
793 
794 
795 static initobjs()
796 {
797 register OBJECTS *ob;
798 register int	 o;
799 
800 	topobj.ob_xnext = topobj.ob_next = &botobj;
801 	botobj.ob_xprev = botobj.ob_prev = &topobj;
802 	topobj.ob_x = -32767;
803 	botobj.ob_x = 32767;
804 
805 	objbot = objtop = deltop = delbot = NULL;
806 	objfree = ob = nobjects;
807 
808 	for ( o = 0; o < MAX_OBJS; ++o ) {
809 		ob->ob_next = ob + 1;
810 		(ob++)->ob_index = o;
811 	}
812 
813 	(--ob)->ob_next = NULL;
814 
815 }
816 
817 
818 
819 initcomp( obp )
820 OBJECTS *obp;
821 {
822 register OBJECTS *ob;
823 OBJECTS 	 *initpln();
824 
825 
826 	ob = initpln( obp );
827 	if ( !obp ) {
828 		ob->ob_drawf = dispcomp;
829 		ob->ob_movef = movecomp;
830 		ob->ob_clr = 2;
831 		if ( ( playmode != MULTIPLE ) && ( playmode != ASYNCH ) )
832 			ob->ob_owner = &nobjects[1];
833 		else
834 			if ( ob->ob_index == 1 )
835 				ob->ob_owner = ob;
836 			else
837 				ob->ob_owner = ob - 2;
838 		movmem( ob, &oobjects[ob->ob_index], sizeof( OBJECTS ) );
839 	}
840 	if ( ( playmode == SINGLE ) || ( playmode == NOVICE ) ){
841 		 ob->ob_state = FINISHED;
842 		 deletex( ob );
843 	}
844 }
845 
846 
847 
848 initplyr( obp )
849 OBJECTS *obp;
850 {
851 register OBJECTS *ob;
852 OBJECTS 	 *initpln();
853 
854 	ob = initpln( obp );
855 	if ( !obp ) {
856 		ob->ob_drawf = dispplyr;
857 		ob->ob_movef = moveplyr;
858 		ob->ob_clr = ob->ob_index % 2 + 1;
859 		ob->ob_owner = ob;
860 		movmem( ob, &oobjects[ob->ob_index], sizeof( OBJECTS ) );
861 		goingsun = FALSE;
862 		endcount = 0;
863 	}
864 
865 	displx = ob->ob_x - SCR_CENTR;
866 	disprx = displx + SCR_WDTH - 1;
867 
868 	swflush();
869 }
870 
871 
872 
873 static	int	inits[2] = { 0, 7 };
874 static	int	initc[4] = { 0, 7, 1, 6 };
875 static	int	initm[8] = { 0, 7, 3, 4, 2, 5, 1, 6 };
876 
877 
878 
879 OBJECTS *initpln( obp )
880 OBJECTS *obp;
881 {
882 register OBJECTS *ob;
883 register int	 x, height, minx, maxx, n;
884 
885 	if ( !obp )
886 		ob = allocobj();
887 	else
888 		ob = obp;
889 
890 	switch ( playmode ) {
891 		case SINGLE:
892 		case NOVICE:
893 			n = inits[ob->ob_index];
894 			break;
895 		case MULTIPLE:
896 		case ASYNCH:
897 			n = initm[ob->ob_index];
898 			break;
899 		case COMPUTER:
900 			n = initc[ob->ob_index];
901 			break;
902 	}
903 
904 	ob->ob_type = PLANE;
905 
906 	ob->ob_x = currgame->gm_x[n];
907 	minx = ob->ob_x;
908 	maxx = ob->ob_x + 20;
909 	height = 0;
910 	for ( x = minx; x <= maxx; ++x )
911 		if ( ground[x] > height )
912 			height = ground[x];
913 	ob->ob_y = height + 13;
914 	ob->ob_lx = ob->ob_ly = ob->ob_speed = ob->ob_flaps = ob->ob_accel
915 		  = ob->ob_hitcount = ob->ob_bdelay = ob->ob_mdelay
916 		  = ob->ob_bsdelay = 0;
917 	setdxdy( ob, 0, 0 );
918 	ob->ob_orient = currgame->gm_orient[n];
919 	ob->ob_angle = ( ob->ob_orient ) ? ( ANGLES / 2 ) : 0;
920 	ob->ob_target = ob->ob_firing = ob->ob_mfiring = NULL;
921 	ob->ob_bombing = ob->ob_bfiring = ob->ob_home = FALSE;
922 	ob->ob_symhgt = SYM_HGHT;
923 	ob->ob_symwdt = SYM_WDTH;
924 	ob->ob_athome = TRUE;
925 	if ( ( !obp ) || ( ob->ob_state == CRASHED )
926 		|| ( ob->ob_state == GHOSTCRASHED ) ) {
927 		ob->ob_rounds = MAXROUNDS;
928 		ob->ob_bombs = MAXBOMBS;
929 		ob->ob_missiles = MAXMISSILES;
930 		ob->ob_bursts = MAXBURSTS;
931 		ob->ob_life = MAXFUEL;
932 	}
933 	if ( !obp ) {
934 		ob->ob_score = ob->ob_updcount = ob->ob_crashcnt
935 			     = endsts[ob->ob_index] = 0;
936 		compnear[ob->ob_index] = NULL;
937 		insertx( ob, &topobj );
938 	} else {
939 		deletex( ob );
940 		insertx( ob, ob->ob_xnext );
941 	}
942 
943 	if ( ( ( playmode == MULTIPLE ) || ( playmode == ASYNCH ) )
944 		&& ( ob->ob_crashcnt >= maxcrash ) ) {
945 		ob->ob_state = GHOST;
946 		if ( ob->ob_index == player )
947 			ghost = TRUE;
948 	} else
949 		ob->ob_state = FLYING;
950 
951 	return( ob );
952 }
953 
954 
955 
956 initshot( obop, targ )
957 OBJECTS *obop, *targ;
958 {
959 register OBJECTS *ob, *obo;
960 int	 nangle, nspeed, dx, dy, r, bspeed, x, y;
961 
962 
963 	if ( ( !targ ) && ( !compplane ) && ( !obo->ob_rounds ))
964 		return;
965 
966 	if ( !( ob = allocobj() ) )
967 		return;
968 
969 	obo = obop;
970 	if ( playmode != NOVICE )
971 		--obo->ob_rounds;
972 
973 	bspeed = BULSPEED + gamenum;
974 
975 	if ( targ ) {
976 		x = targ->ob_x + ( targ->ob_dx << 2 );
977 		y = targ->ob_y + ( targ->ob_dy << 2 );
978 		dx = x - obo->ob_x;
979 		dy = y - obo->ob_y;
980 		if ( ( r = isrange( x, y, obo->ob_x, obo->ob_y ) ) < 1 ) {
981 			deallobj( ob );
982 			return;
983 		}
984 		ob->ob_dx = ( dx * bspeed ) / r;
985 		ob->ob_dy = ( dy * bspeed ) / r;
986 		ob->ob_ldx = ob->ob_ldy = 0;
987 	} else {
988 		nspeed = obo->ob_speed + bspeed;
989 		nangle = obo->ob_angle;
990 		setdxdy( ob, nspeed * COS( nangle ),
991 			     nspeed * SIN( nangle ) );
992 	}
993 
994 	ob->ob_type = SHOT;
995 	ob->ob_x = obo->ob_x + SYM_WDTH / 2;
996 	ob->ob_y = obo->ob_y - SYM_HGHT / 2;
997 	ob->ob_lx = obo->ob_lx;
998 	ob->ob_ly = obo->ob_ly;
999 
1000 
1001 	ob->ob_life = BULLIFE;
1002 	ob->ob_owner = obo;
1003 	ob->ob_clr = obo->ob_clr;
1004 	ob->ob_symhgt = ob->ob_symwdt = 1;
1005 	ob->ob_drawf = NULL;
1006 	ob->ob_movef = moveshot;
1007 	ob->ob_speed = 0;
1008 
1009 	insertx( ob, obo );
1010 
1011 }
1012 
1013 
1014 
1015 
1016 
1017 static isrange( x, y, ax, ay )
1018 int	x, y, ax, ay;
1019 {
1020 register int	 dx, dy, t;
1021 
1022 	dy = abs( y - ay );
1023 	dy += dy >> 1;
1024 	if ( ( ( dx = abs( x - ax ) ) > 100 ) || ( dy > 100 ) )
1025 		return ( -1 );
1026 
1027 	if ( dx < dy ) {
1028 		t = dx;
1029 		dx = dy;
1030 		dy = t;
1031 	}
1032 
1033 	return( ( ( 7 * dx ) + ( dy << 2 ) ) >> 3 );
1034 }
1035 
1036 
1037 
1038 initbomb( obop )
1039 OBJECTS *obop;
1040 {
1041 register OBJECTS *ob, *obo;
1042 int		 angle;
1043 
1044 	obo = obop;
1045 	if ( ( ( !compplane) && ( !obo->ob_bombs ) ) || ( obo->ob_bdelay ) )
1046 		return;
1047 	if ( !( ob = allocobj() ) )
1048 		return;
1049 
1050 	if ( playmode != NOVICE )
1051 		--obo->ob_bombs;
1052 
1053 	obo->ob_bdelay = 10;
1054 
1055 	ob->ob_type = BOMB;
1056 	ob->ob_state = FALLING;
1057 	ob->ob_dx = obo->ob_dx;
1058 	ob->ob_dy = obo->ob_dy;
1059 
1060 	if ( obo->ob_orient )
1061 		angle = ( obo->ob_angle + ( ANGLES / 4 ) ) % ANGLES;
1062 	else
1063 		angle = ( obo->ob_angle + ( 3 * ANGLES / 4 ) ) % ANGLES;
1064 	ob->ob_x = obo->ob_x + ( ( COS( angle ) * 10 ) >> 8 ) + 4;
1065 	ob->ob_y = obo->ob_y + ( ( SIN( angle ) * 10 ) >> 8 ) - 4;
1066 	ob->ob_lx = ob->ob_ly = ob->ob_ldx = ob->ob_ldy = 0;
1067 
1068 	ob->ob_life = BOMBLIFE;
1069 	ob->ob_owner = obo;
1070 	ob->ob_clr = obo->ob_clr;
1071 	ob->ob_symhgt = ob->ob_symwdt = 8;
1072 	ob->ob_drawf = dispbomb;
1073 	ob->ob_movef = movebomb;
1074 
1075 	insertx( ob, obo );
1076 
1077 }
1078 
1079 
1080 
1081 initmiss( obop )
1082 OBJECTS *obop;
1083 {
1084 register OBJECTS *ob, *obo;
1085 int		 angle, nspeed;
1086 
1087 	obo = obop;
1088 	if ( obo->ob_mdelay || ( !obo->ob_missiles ) || !missok )
1089 		return;
1090 	if ( !( ob = allocobj() ) )
1091 		return;
1092 
1093 	if ( playmode != NOVICE )
1094 		--obo->ob_missiles;
1095 
1096 	obo->ob_mdelay = 5;
1097 
1098 	ob->ob_type = MISSILE;
1099 	ob->ob_state = FLYING;
1100 
1101 	angle = ob->ob_angle = obo->ob_angle;
1102 	ob->ob_x = obo->ob_x + ( COS( angle ) >> 4 ) + 4;
1103 	ob->ob_y = obo->ob_y + ( SIN( angle ) >> 4 ) - 4;
1104 	ob->ob_lx = ob->ob_ly = 0;
1105 	ob->ob_speed = nspeed = gmaxspeed + ( gmaxspeed >> 1 );
1106 	setdxdy( ob, nspeed * COS( angle ), nspeed * SIN( angle ) );
1107 
1108 	ob->ob_life = MISSLIFE;
1109 	ob->ob_owner = obo;
1110 	ob->ob_clr = obo->ob_clr;
1111 	ob->ob_symhgt = ob->ob_symwdt = 8;
1112 	ob->ob_drawf = dispmiss;
1113 	ob->ob_movef = movemiss;
1114 	ob->ob_target = obo->ob_mfiring;
1115 	ob->ob_orient = ob->ob_accel = ob->ob_flaps = 0;
1116 
1117 	insertx( ob, obo );
1118 
1119 }
1120 
1121 
1122 
1123 initburst( obop )
1124 OBJECTS *obop;
1125 {
1126 register OBJECTS *ob, *obo;
1127 int		 angle;
1128 
1129 	obo = obop;
1130 	if ( obo->ob_bsdelay || ( !obo->ob_bursts ) || !missok )
1131 		return;
1132 	if ( !( ob = allocobj() ) )
1133 		return;
1134 
1135 	ob->ob_bsdelay = 5;
1136 
1137 	if ( playmode != NOVICE )
1138 		--obo->ob_bursts;
1139 
1140 	ob->ob_type = STARBURST;
1141 	ob->ob_state = FALLING;
1142 
1143 	if ( obo->ob_orient )
1144 		angle = ( obo->ob_angle + ( 3 * ANGLES / 8 ) ) % ANGLES;
1145 	else
1146 		angle = ( obo->ob_angle + ( 5 * ANGLES / 8 ) ) % ANGLES;
1147 	setdxdy( ob, gminspeed * COS( angle ), gminspeed * SIN( angle ) );
1148 	ob->ob_dx += obo->ob_dx;
1149 	ob->ob_dy += obo->ob_dy;
1150 
1151 	ob->ob_x = obo->ob_x + ( ( COS( angle ) * 10 ) >> 10 ) + 4;
1152 	ob->ob_y = obo->ob_y + ( ( SIN( angle ) * 10 ) >> 10 ) - 4;
1153 	ob->ob_lx = ob->ob_ly = 0;
1154 
1155 	ob->ob_life = BURSTLIFE;
1156 	ob->ob_owner = obo;
1157 	ob->ob_clr = obo->ob_clr;
1158 	ob->ob_symhgt = ob->ob_symwdt = 8;
1159 	ob->ob_drawf = dispburst;
1160 	ob->ob_movef = moveburst;
1161 
1162 	insertx( ob, obo );
1163 
1164 }
1165 
1166 
1167 
1168 static inittarg()
1169 {
1170 register OBJECTS *ob;
1171 register int x, i;
1172 int	*tx, *tt;
1173 int	minh, maxh, aveh, minx, maxx;
1174 
1175 	tx = currgame->gm_xtarg;
1176 	tt = currgame->gm_ttarg;
1177 
1178 	if ( ( ( playmode != MULTIPLE ) && ( playmode != ASYNCH ) )
1179 		|| ( multbuff->mu_maxplyr == 1 ) ) {
1180 		numtarg[0] = 0;
1181 		numtarg[1] = MAX_TARG - 3;
1182 	} else
1183 		numtarg[0] = numtarg[1] = MAX_TARG / 2;
1184 
1185 	for ( i = 0; i < MAX_TARG; ++i, ++tx, ++tt ) {
1186 		targets[i] = ob = allocobj();
1187 		minx = ob->ob_x = *tx;
1188 		maxx = ob->ob_x + 15;
1189 		minh = 999;
1190 		maxh = 0;
1191 		for ( x = minx; x <= maxx; ++x ) {
1192 			if ( ground[x] > maxh )
1193 				maxh = ground[x];
1194 			if ( ground[x] < minh )
1195 				minh = ground[x];
1196 		}
1197 		aveh = ( minh + maxh ) >> 1;
1198 
1199 		while ( ( ob->ob_y = aveh + 16 ) >= MAX_Y )
1200 			--aveh;
1201 
1202 		for ( x = minx; x <= maxx; ++x )
1203 			ground[x] = aveh;
1204 
1205 		ob->ob_dx = ob->ob_dy = ob->ob_lx = ob->ob_ly = ob->ob_ldx
1206 			  = ob->ob_ldy = ob->ob_angle = ob->ob_hitcount = 0;
1207 		ob->ob_type = TARGET;
1208 		ob->ob_state = STANDING;
1209 		ob->ob_orient = *tt;
1210 		ob->ob_life = i;
1211 
1212 		if ( ( ( playmode != MULTIPLE ) && ( playmode != ASYNCH ) )
1213 			|| ( multbuff->mu_maxplyr == 1 ) )
1214 			ob->ob_owner = &nobjects[( ( i < MAX_TARG / 2 )
1215 						 && ( i > MAX_TARG /2 - 4 ) )
1216 						 ? 0 : 1 ];
1217 		else
1218 			ob->ob_owner = &nobjects[i >= ( MAX_TARG / 2 ) ];
1219 		ob->ob_clr = ob->ob_owner->ob_clr;
1220 		ob->ob_symhgt = ob->ob_symwdt = 16;
1221 		ob->ob_drawf = disptarg;
1222 		ob->ob_movef = movetarg;
1223 
1224 		insertx( ob, &topobj );
1225 	}
1226 }
1227 
1228 
1229 
1230 initexpl( obop, small )
1231 OBJECTS *obop;
1232 int	small;
1233 {
1234 register OBJECTS *ob, *obo;
1235 int	 i, ic, life, speed;
1236 int	 obox, oboy, obodx, obody, oboclr, obotype;
1237 BOOL	 mansym;
1238 int	 orient;
1239 
1240 
1241 	obo = obop;
1242 	obox   = obo->ob_x + ( obo->ob_symwdt >> 1 );
1243 	oboy   = obo->ob_y + ( obo->ob_symhgt >> 1 );
1244 	obodx  = obo->ob_dx >> 2;
1245 	obody  = obo->ob_dy >> 2;
1246 	oboclr = obo->ob_clr;
1247 
1248 	if ( ( ( obotype = obo->ob_type ) == TARGET )
1249 		&& ( obo->ob_orient == 2 ) ) {
1250 		ic = 1;
1251 		speed = gminspeed;
1252 	} else {
1253 		ic = small ? 6 : 2;
1254 		speed = gminspeed >> ( ( explseed & 7 ) != 7 );
1255 	}
1256 	mansym = ( obotype == PLANE ) && ( ( obo->ob_state == FLYING )
1257 				      || ( obo->ob_state == WOUNDED ) );
1258 
1259 	for ( i = 1; i <= 15; i += ic ) {
1260 		if ( !( ob = allocobj() ) )
1261 			return;
1262 
1263 		ob->ob_type = EXPLOSION;
1264 
1265 		setdxdy( ob, COS( i ) * speed, SIN( i ) * speed );
1266 		ob->ob_dx += obodx;
1267 		ob->ob_dy += obody;
1268 
1269 		if ( !( explseed = ( ob->ob_x = obox + ob->ob_dx )
1270 			* ( ob->ob_y = oboy + ob->ob_dy )
1271 			* explseed + 7491 ) )
1272 			explseed = 74917777;
1273 
1274 		ob->ob_life = EXPLLIFE;
1275 		orient = ob->ob_orient =   ( explseed & 0x01C0 ) >> 6;
1276 		if ( mansym && ( ( !orient ) || ( orient == 7 ) ) ) {
1277 			mansym = orient = ob->ob_orient = 0;
1278 			ob->ob_dx = obodx;
1279 			ob->ob_dy = -gminspeed;
1280 		}
1281 
1282 		ob->ob_lx = ob->ob_ly = ob->ob_hitcount = ob->ob_speed = 0;
1283 		ob->ob_owner = obo;
1284 		ob->ob_clr = oboclr;
1285 		ob->ob_symhgt = ob->ob_symwdt = 8;
1286 		ob->ob_drawf = dispexpl;
1287 		ob->ob_movef = moveexpl;
1288 
1289 		if ( orient )
1290 			initsound( ob, S_EXPLOSION );
1291 
1292 		insertx( ob, obo );
1293 	}
1294 }
1295 
1296 
1297 
1298 initsmok( obop )
1299 OBJECTS *obop;
1300 {
1301 register OBJECTS *ob, *obo;
1302 
1303 
1304 	if ( !( ob = allocobj() ) )
1305 		return;
1306 
1307 	ob->ob_type = SMOKE;
1308 
1309 	ob->ob_x = ( obo = obop )->ob_x + 8;
1310 	ob->ob_y = obo->ob_y - 8;
1311 	ob->ob_dx = obo->ob_dx;
1312 	ob->ob_dy = obo->ob_dy;
1313 	ob->ob_lx = ob->ob_ly = ob->ob_ldx = ob->ob_ldy = 0;
1314 	ob->ob_life = SMOKELIFE;
1315 	ob->ob_owner = obo;
1316 	ob->ob_symhgt = ob->ob_symwdt = 1;
1317 	ob->ob_drawf = NULL;
1318 	ob->ob_movef = movesmok;
1319 	ob->ob_clr = obo->ob_clr;
1320 }
1321 
1322 
1323 
1324 
1325 static	ifx[] = { MINFLCKX, MINFLCKX + 1000, MAXFLCKX - 1000, MAXFLCKX };
1326 static	ify[] = { MAX_Y-1,  MAX_Y-1,	     MAX_Y-1,	      MAX_Y-1  };
1327 static	ifdx[] = { 2,	    2,		     -2,	      -2       };
1328 
1329 
1330 
1331 initflck()
1332 {
1333 register OBJECTS *ob;
1334 register int	 i, j;
1335 
1336 	if ( playmode == NOVICE )
1337 		return;
1338 
1339 	for ( i = 0; i < MAX_FLCK; ++i ) {
1340 
1341 		if ( !( ob = allocobj() ) )
1342 			return;
1343 
1344 		ob->ob_type = FLOCK;
1345 		ob->ob_state = FLYING;
1346 		ob->ob_x = ifx[i];
1347 		ob->ob_y = ify[i];
1348 		ob->ob_dx = ifdx[i];
1349 		ob->ob_dy = ob->ob_lx = ob->ob_ly = ob->ob_ldx = ob->ob_ldy = 0;
1350 		ob->ob_orient = 0;
1351 		ob->ob_life = FLOCKLIFE;
1352 		ob->ob_owner = ob;
1353 		ob->ob_symhgt = ob->ob_symwdt = 16;
1354 		ob->ob_drawf = dispflck;
1355 		ob->ob_movef = moveflck;
1356 		ob->ob_clr = 9;
1357 		insertx( ob, &topobj );
1358 		for ( j = 0; j < MAX_BIRD; ++j )
1359 			initbird( ob, 1 );
1360 	}
1361 }
1362 
1363 
1364 
1365 initbird( obop, i )
1366 OBJECTS *obop;
1367 int	i;
1368 {
1369 register OBJECTS *ob, *obo;
1370 static	 ibx[] = { 8, 3, 0, 6, 7, 14, 10, 12 };
1371 static	 iby[] = { 16, 1, 8, 3, 12, 10, 7, 14 };
1372 static	 ibdx[] = { -2, 2, -3, 3, -1, 1, 0, 0 };
1373 static	 ibdy[] = { -1, -2, -1, -2, -1, -2, -1, -2 };
1374 
1375 
1376 	if ( !( ob = allocobj() ) )
1377 		return;
1378 
1379 	ob->ob_type = BIRD;
1380 
1381 	ob->ob_x = ( obo = obop )->ob_x + ibx[i];
1382 	ob->ob_y = obo->ob_y - iby[i];
1383 	ob->ob_dx = ibdx[i];
1384 	ob->ob_dy = ibdy[i];
1385 	ob->ob_orient = ob->ob_lx = ob->ob_ly = ob->ob_ldx = ob->ob_ldy = 0;
1386 	ob->ob_life = BIRDLIFE;
1387 	ob->ob_owner = obo;
1388 	ob->ob_symhgt = 2;
1389 	ob->ob_symwdt = 4;
1390 	ob->ob_drawf = dispbird;
1391 	ob->ob_movef = movebird;
1392 	ob->ob_clr = obo->ob_clr;
1393 	insertx( ob, obo );
1394 }
1395 
1396 
1397 
1398 initoxen()
1399 {
1400 register OBJECTS *ob;
1401 register int	  i;
1402 static	 iox[] = { 1376, 1608 };
1403 static	 ioy[] = { 80,	 91   };
1404 
1405 	if ( playmode == NOVICE ) {
1406 		for ( i = 0; i < MAX_OXEN; ++i )
1407 			targets[MAX_TARG + i] = NULL;
1408 		return;
1409 	}
1410 
1411 	for ( i = 0; i < MAX_OXEN; ++i ) {
1412 		if ( !( targets[MAX_TARG + i] = ob = allocobj() ) )
1413 			return;
1414 
1415 		ob->ob_type = OX;
1416 		ob->ob_state = STANDING;
1417 		ob->ob_x = iox[i];
1418 		ob->ob_y = ioy[i];
1419 		ob->ob_orient = ob->ob_lx = ob->ob_ly = ob->ob_ldx = ob->ob_ldy
1420 			      = ob->ob_dx = ob->ob_dy = 0;
1421 		ob->ob_owner = ob;
1422 		ob->ob_symhgt = 16;
1423 		ob->ob_symwdt = 16;
1424 		ob->ob_drawf = NULL;
1425 		ob->ob_movef = moveox;
1426 		ob->ob_clr = 1;
1427 		insertx( ob, &topobj );
1428 	}
1429 }
1430 