1 /*
2 
3 	swgrph	 -	SW screen graphics
4 
5 	Copyright (C) 1984-2003 David L. Clark.
6 	This program is free software; you can redistribute it and/or modify it under
7 	the terms of the GNU General Public License as published by the Free Software
8 	Foundation; either version 2 of the License, or (at your option) any later
9 	version. This program is distributed in the hope that it will be useful,
10 	but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 	or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 	more details. You should have received a copy of the GNU General Public
13 	License along with this program; if not, write to the Free Software Foundation,
14 	Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
15 
16 			Author: Dave Clark
17 
18 	Modification History:
19 			84-02-21	Development
20 			84-06-13	PCjr Speed-up
21 			85-11-05	Atari
22 			87-03-09	Microsoft compiler.
23 			2003-01-27	GNU General Public License
24 */
25 
26 
27 
28 
29 #include	"sw.h"
30 
31 
32 
33 extern	int	displx, disprx; 	/* Display left and right bounds    */
34 extern	int	dispdx; 		/* Display shift		    */
35 extern	char	auxdisp[];		/* Auxiliary display area	    */
36 extern	GRNDTYPE ground[];		/* Ground height by pixel	    */
37 extern	BOOL	dispinit;		/* Initalized display flag.	    */
38 extern	OBJECTS *objtop;		/* Top of object list		    */
39 extern	OBJECTS *deltop;		/* Newly deallocated objects list   */
40 extern	int	forcdisp;		/* Force display of ground	    */
41 extern	long	trap14();		/* BIOS trap			    */
42 
43 static	char	*dispoff;		/* Current display offset	    */
44 static	int	scrtype;		/* Screen type			    */
45 static	GRNDTYPE grndsave[SCR_WDTH];	/* Saved ground buffer for last     */
46 					/*   last display		    */
47 static	int	( *dispg )();		/* display ground routine (mono,clr)*/
48 static	int	( *drawpnt )(); 	/* draw point routine		    */
49 static	int	( *drawsym )(); 	/* draw symbol routine		    */
50 
51 static	int	palette[] = {	/* Colour palette			    */
52 	0x000,			/*   0 = black	  background		    */
53 	0x037,			/*   1 = blue	  planes,targets,explosions */
54 	0x700,			/*   2 = red	  planes,targets,explosions */
55 	0x777,			/*   3 = white	  bullets		    */
56 	0x000,			/*   4					    */
57 	0x000,			/*   5					    */
58 	0x000,			/*   6					    */
59 	0x070,			/*   7 = green	  ground		    */
60 	0x000,			/*   8					    */
61 	0x433,			/*   9 = tan	  oxen, birds		    */
62 	0x420,			/*  10 = brown	  oxen			    */
63 	0x320,			/*  11 = brown	  bottom of ground display  */
64 	0x000,			/*  12					    */
65 	0x000,			/*  13					    */
66 	0x000,			/*  14					    */
67 	0x000			/*  15					    */
68 };
69 
70 
71 
72 static	char	spcbirds[BIRDSYMS][BRDBYTES*2];   /* Special bird symbol    */
73 						  /* colour video maps	    */
74 
75 
76 
77 
78 /*---------------------------------------------------------------------------
79 
80 	Main display loop.   Delete and display all visible objects.
81 	Delete any newly deleted objects
82 
83 ---------------------------------------------------------------------------*/
84 
85 
86 
87 swdisp()
88 {
89 register OBJECTS *ob;
90 
91 	setvdisp();
92 	for ( ob = objtop; ob; ob = ob->ob_next ) {
93 		if ( ( !( ob->ob_delflg && ob->ob_drwflg ) )
94 			|| ( ob->ob_symhgt == 1 )
95 			|| ( ob->ob_oldsym != ob->ob_newsym )
96 			|| ( ob->ob_y != ob->ob_oldy )
97 			|| ( ( ob->ob_oldx + displx ) != ob->ob_x ) ) {
98 			if ( ob->ob_delflg )
99 				( *drawsym )( ob, ob->ob_oldx, ob->ob_oldy,
100 					      ob->ob_oldsym, ob->ob_clr, NULL );
101 			if ( !ob->ob_drwflg )
102 				continue;
103 			if ( ( ob->ob_x < displx ) || ( ob->ob_x > disprx ) ) {
104 				ob->ob_drwflg = 0;
105 				continue;
106 			}
107 			( *drawsym )( ob, ob->ob_oldx = ob->ob_x - displx,
108 				      ob->ob_oldy = ob->ob_y,
109 				      ob->ob_newsym,
110 				      ob->ob_clr, NULL );
111 		}
112 		if ( ob->ob_drawf )
113 			( *( ob->ob_drawf ) )( ob );
114 	}
115 
116 	for ( ob = deltop; ob; ob = ob->ob_next )
117 		if ( ob->ob_delflg )
118 			( *drawsym )( ob, ob->ob_oldx, ob->ob_oldy,
119 				      ob->ob_oldsym, ob->ob_clr, NULL );
120 
121 	dispgrnd();
122 	dispinit = FALSE;
123 	forcdisp = FALSE;
124 }
125 
126 
127 
128 /*---------------------------------------------------------------------------
129 
130 	Update display of ground.   Delete previous display of ground by
131 	XOR graphics.
132 
133 	Different routines are used to display/delete ground on colour
134 	or monochrome systems.
135 
136 ---------------------------------------------------------------------------*/
137 
138 
139 
140 
141 static	dispgrnd()
142 {
143 	if ( !dispinit ) {
144 		if ( !( dispdx || forcdisp ) )
145 			return;
146 		( *dispg )( grndsave );
147 	}
148 	movmem( ground + displx, grndsave, SCR_WDTH * sizeof( GRNDTYPE ) );
149 	( *dispg )( ground + displx );
150 }
151 
152 
153 
154 
155 static	dispgm( gptr )
156 GRNDTYPE *gptr;
157 {
158 register GRNDTYPE *g, gl, gc;
159 register int	  gmask, i;
160 register char	  *sptr;
161 
162 	i = SCR_WDTH;
163 	gl = *( g = gptr );
164 	gmask = 0xC0;
165 	sptr = dispoff + ( SCR_HGHT - gl - 1 ) * 160;
166 
167 	while ( i-- ) {
168 		if ( gl == ( gc = *g++ ) ) {
169 			*sptr	     ^= gmask;
170 			*( sptr+80 ) ^= gmask;
171 		} else if ( gl < gc )
172 			do  {
173 				*( sptr-=160 ) ^= gmask;
174 				*( sptr+80 )   ^= gmask;
175 			} while ( ++gl < gc );
176 		else
177 			do  {
178 				*( sptr+=160 ) ^= gmask;
179 				*( sptr-80 )   ^= gmask;
180 			} while ( --gl > gc );
181 
182 		if ( !( gmask >>= 2 ) ) {
183 			gmask = 0xC0;
184 			++sptr;
185 		}
186 	}
187 }
188 
189 
190 
191 
192 static	dispgc( gptr )
193 GRNDTYPE *gptr;
194 {
195 register GRNDTYPE *g, gl, gc;
196 register int	  gmask, i;
197 register char	  *sptr;
198 
199 	i = SCR_WDTH;
200 	gl = *( g = gptr );
201 	gmask = 0x80;
202 	sptr = dispoff + ( SCR_HGHT - gl - 1 ) * 160;
203 
204 	while ( i-- ) {
205 		if ( gl == ( gc = *g++ ) ) {
206 			*sptr	    ^= gmask;
207 			*( sptr+2 ) ^= gmask;
208 			*( sptr+4 ) ^= gmask;
209 		} else if ( gl < gc )
210 			do  {
211 				*( sptr-=160 ) ^= gmask;
212 				*( sptr+2 )    ^= gmask;
213 				*( sptr+4 )    ^= gmask;
214 			} while ( ++gl < gc );
215 		else
216 			do  {
217 				*( sptr+=160 ) ^= gmask;
218 				*( sptr+2 )    ^= gmask;
219 				*( sptr+4 )    ^= gmask;
220 			} while ( --gl > gc );
221 
222 		if ( !( gmask >>= 1 ) ) {
223 			gmask = 0x80;
224 			if ( (long) sptr & 1 )
225 				sptr += 7;
226 			else
227 				++sptr;
228 		}
229 	}
230 }
231 
232 
233 
234 /*---------------------------------------------------------------------------
235 
236 	External display ground call for title screen processing.
237 
238 ---------------------------------------------------------------------------*/
239 
240 
241 
242 
243 swground()
244 {
245 	dispgrnd();
246 }
247 
248 
249 
250 /*---------------------------------------------------------------------------
251 
252 	Clear the collision detection portion of auxiliary video ram
253 
254 ---------------------------------------------------------------------------*/
255 
256 
257 
258 
259 swclrcol()
260 {
261 register long	*sptr;
262 register int	l;
263 
264 	sptr = dispoff + ( SCR_HGHT - 1 ) * 160;
265 	if ( scrtype == 2 )
266 		for ( l = 32; l; --l ) {
267 			*sptr = *( sptr + 1 ) = *( sptr + 2 ) = 0L;
268 			sptr -= 20;
269 		}
270 	else
271 		for ( l = 16; l; --l ) {
272 			*sptr = *( sptr + 1 ) = *( sptr + 2 ) = *( sptr + 3 )
273 			      = *( sptr + 4 ) = *( sptr + 5 ) = 0L;
274 			sptr -= 40;
275 		}
276 }
277 
278 
279 
280 /*---------------------------------------------------------------------------
281 
282 	Display an object's current symbol at a specified screen location
283 	Collision detection may or may not be asked for.
284 
285 	Different routines are used to display symbols on colour or
286 	monochrome systems.
287 
288 ---------------------------------------------------------------------------*/
289 
290 
291 
292 
293 swputsym( x, y, ob )
294 int	x, y;
295 OBJECTS *ob;
296 {
297 	( *drawsym )( ob, x, y, ob->ob_newsym, ob->ob_clr, NULL );
298 }
299 
300 
301 
302 swputcol( x, y, ob )
303 int	x, y;
304 OBJECTS *ob;
305 {
306 int	retcode = FALSE;
307 
308 	( *drawsym )( ob, x, y, ob->ob_newsym, ob->ob_clr, &retcode );
309 	return( retcode );
310 }
311 
312 
313 
314 
315 char	fill[] = {
316 0x00,0x03,0x03,0x03,0x0C,0x0F,0x0F,0x0F,0x0C,0x0F,0x0F,0x0F,0x0C,0x0F,0x0F,0x0F,
317 0x30,0x33,0x33,0x33,0x3C,0x3F,0x3F,0x3F,0x3C,0x3F,0x3F,0x3F,0x3C,0x3F,0x3F,0x3F,
318 0x30,0x33,0x33,0x33,0x3C,0x3F,0x3F,0x3F,0x3C,0x3F,0x3F,0x3F,0x3C,0x3F,0x3F,0x3F,
319 0x30,0x33,0x33,0x33,0x3C,0x3F,0x3F,0x3F,0x3C,0x3F,0x3F,0x3F,0x3C,0x3F,0x3F,0x3F,
320 0xC0,0xC3,0xC3,0xC3,0xCC,0xCF,0xCF,0xCF,0xCC,0xCF,0xCF,0xCF,0xCC,0xCF,0xCF,0xCF,
321 0xF0,0xF3,0xF3,0xF3,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,
322 0xF0,0xF3,0xF3,0xF3,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,
323 0xF0,0xF3,0xF3,0xF3,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,
324 0xC0,0xC3,0xC3,0xC3,0xCC,0xCF,0xCF,0xCF,0xCC,0xCF,0xCF,0xCF,0xCC,0xCF,0xCF,0xCF,
325 0xF0,0xF3,0xF3,0xF3,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,
326 0xF0,0xF3,0xF3,0xF3,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,
327 0xF0,0xF3,0xF3,0xF3,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,
328 0xC0,0xC3,0xC3,0xC3,0xCC,0xCF,0xCF,0xCF,0xCC,0xCF,0xCF,0xCF,0xCC,0xCF,0xCF,0xCF,
329 0xF0,0xF3,0xF3,0xF3,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,
330 0xF0,0xF3,0xF3,0xF3,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,
331 0xF0,0xF3,0xF3,0xF3,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF
332 };
333 
334 
335 
336 
337 static	drawsm( ob, x, y, symbol, clr, retcode )
338 OBJECTS *ob;
339 int	x, y, clr, *retcode;
340 char	*symbol;
341 {
342 register char	*s, *sptr, *sym;
343 register int	j, c, cr, pc;
344 int		rotr, rotl, wdth, wrap, n;
345 
346 	if ( !( sym = symbol ) )
347 		return;
348 
349 	if ( ( ob->ob_symhgt == 1 ) && ( ob->ob_symwdt == 1 ) ) {
350 		drawpm( x, y, (int) sym, retcode );
351 		return;
352 	}
353 
354 	rotr = ( x & 0x0003 ) << 1;
355 	rotl = 8 - rotr;
356 
357 	if ( ( wrap = ( wdth = ob->ob_symwdt >> 2 )
358 		- ( n = SCR_LINW - ( x >> 2 ) ) ) > 0 )
359 		wdth = n;
360 
361 	if ( ( n = ob->ob_symhgt ) > ( y + 1 ) )
362 		n = y + 1;
363 	sptr = dispoff + ( ( SCR_HGHT - y - 1 ) * 160 ) + ( x >> 2 );
364 
365 	while ( n-- ) {
366 		s = sptr;
367 		j = wdth;
368 		pc = 0;
369 		while ( j-- ) {
370 			cr = ( c = *sym++ ) << rotl;
371 			c = ( ( c & 0x00FF ) >> rotr ) | pc;
372 			pc = cr;
373 			if ( retcode && ( *s & fill[c & 0x00FF] ) ){
374 				*retcode = TRUE;
375 				retcode = 0;
376 			}
377 			*s ^= c;
378 			*((s++)+80) ^= c;
379 		}
380 		if ( wrap >= 0 )
381 			sym += wrap;
382 		else {
383 			if ( retcode && ( *s & fill[pc & 0x00FF ] ) ){
384 				*retcode = TRUE;
385 				retcode = 0;
386 			}
387 			*s	^= pc;
388 			*(s+80) ^= pc;
389 		}
390 		sptr += 160;
391 	}
392 }
393 
394 
395 
396 
397 static	drawsc( ob, x, y, symbol, clr, retcode )
398 OBJECTS *ob;
399 int	x, y, clr, *retcode;
400 char	*symbol;
401 {
402 register char	*s, *sptr, *sym;
403 register int	j, c1, c2, c;
404 int		rotr, rotl, wdth, wrap, n;
405 int		cr, pc1, pc2, invert, enhance1;
406 extern	char	swbrdsym[BIRDSYMS][BRDBYTES];
407 
408 	if ( !( sym = symbol ) )
409 		return;
410 
411 	if ( ( ob->ob_symhgt == 1 ) && ( ob->ob_symwdt == 1 ) ) {
412 		drawpc( x, y, (int) sym, retcode );
413 		return;
414 	}
415 
416 	rotr = x & 0x0007;
417 	rotl = 8 - rotr;
418 
419 	if ( ( wrap = ( wdth = ob->ob_symwdt >> 2 )
420 		- ( n = SCR_LINW - ( x >> 2 ) ) ) > 0 )
421 		wdth = n;
422 
423 	if ( ( n = ob->ob_symhgt ) > ( y + 1 ) )
424 		n = y + 1;
425 	sptr = dispoff + ( ( SCR_HGHT - y - 1 ) * 160 )
426 		       + ( ( x & 0xFFF0 ) >> 1 )
427 		       + ( ( x & 0x0008 ) >> 3 );
428 
429 	invert = ( clr & 0x0003 ) == 2 ? -1 : 0;
430 	enhance1 = ( ( ( j = ob->ob_type ) == FLOCK ) || ( j == BIRD )
431 		   || ( j == OX ) ) ? -1 : 0;
432 	if ( j == BIRD )
433 		sym = (char *) spcbirds + ( ( sym - (char *) swbrdsym ) << 1 );
434 
435 	while ( n-- ) {
436 		s = sptr;
437 		j = wdth;
438 		pc1 = pc2 = 0;
439 		while ( j-- ) {
440 			if ( j ) {
441 				c = 0xFF;
442 				--j;
443 			} else
444 				c = 0xF0;
445 
446 			cr = ( c1 = *sym++ & c ) << rotl;
447 			c1 = ( c1 >> rotr ) | pc1;
448 			pc1 = cr;
449 			cr = ( c2 = *sym++ & c ) << rotl;
450 			c2 = ( c2 >> rotr ) | pc2;
451 			pc2 = cr;
452 			c = c1 | c2;
453 
454 			if ( retcode
455 				&& ( c & ( *s | *(s+2) ) & 0xFF ) ) {
456 				*retcode = TRUE;
457 				retcode = 0;
458 			}
459 			*s     ^= c1 ^ ( c & invert );
460 			*(s+2) ^= c2 ^ ( c & invert );
461 			*(s+6) ^= c & enhance1;
462 
463 			if ( (long) s & 1 )
464 				s += 7;
465 			else
466 				++s;
467 		}
468 		if ( wrap >= 0 )
469 			sym += wrap & 0xFFFE;
470 		else {
471 			c = pc1 | pc2;
472 			if ( retcode
473 				&& ( c & ( *s | *(s+2) ) & 0xFF ) ){
474 				*retcode = TRUE;
475 				retcode = 0;
476 			}
477 			*s     ^= pc1 ^ ( c & invert );
478 			*(s+2) ^= pc2 ^ ( c & invert );
479 			*(s+6) ^= c & enhance1;
480 		}
481 		sptr += 160;
482 	}
483 }
484 
485 
486 
487 /*---------------------------------------------------------------------------
488 
489 	External calls to display a point of a specified colour at a
490 	specified position.   The point request may or may not ask for
491 	collision detection by returning the old colour of the point.
492 
493 	Different routines are used to display points on colour or
494 	monochrome systems.
495 
496 ---------------------------------------------------------------------------*/
497 
498 
499 
500 
501 swpntsym( x, y, clr )
502 int	x, y, clr;
503 {
504 	( *drawpnt )( x, y, clr, NULL );
505 }
506 
507 
508 
509 swpntcol( x, y, clr )
510 int	x, y, clr;
511 {
512 int	oldclr;
513 
514 	( *drawpnt )( x, y, clr, &oldclr );
515 	return( oldclr );
516 }
517 
518 
519 
520 drawpc( x, y, clr, oldclr )
521 int	x, y, clr, *oldclr;
522 {
523 register  int	c, mask;
524 register  char	*sptr;
525 
526 	sptr = dispoff + ( ( SCR_HGHT - y - 1 ) * 160 )
527 		       + ( ( x & 0xFFF0 ) >> 1 )
528 		       + ( ( x & 0x0008 ) >> 3 );
529 	mask = 0x80 >> ( x &= 0x0007 );
530 
531 	if ( oldclr ) {
532 		c = ( *sptr & mask )
533 			| ( ( *( sptr+2 ) & mask ) << 1 )
534 			| ( ( *( sptr+4 ) & mask ) << 2 )
535 			| ( ( *( sptr+6 ) & mask ) << 3 );
536 		*oldclr = ( c >> ( 7 - x ) ) & 0x00FF;
537 	}
538 
539 	c = clr << ( 7 - x );
540 	if ( clr & 0x0080 ) {
541 		*sptr	    ^= ( mask & c );
542 		*( sptr+2 ) ^= ( mask & ( c >> 1 ) );
543 		*( sptr+4 ) ^= ( mask & ( c >> 2 ) );
544 		*( sptr+6 ) ^= ( mask & ( c >> 3 ) );
545 	} else {
546 		mask = ~mask;
547 		*sptr	    &= mask;
548 		*( sptr+2 ) &= mask;
549 		*( sptr+4 ) &= mask;
550 		*( sptr+6 ) &= mask;
551 
552 		mask = ~mask;
553 		*sptr	    |= ( mask & c );
554 		*( sptr+2 ) |= ( mask & ( c >> 1 ) );
555 		*( sptr+4 ) |= ( mask & ( c >> 2 ) );
556 		*( sptr+6 ) |= ( mask & ( c >> 3 ) );
557 	}
558 }
559 
560 
561 
562 
563 
564 drawpm( x, y, clr, oldclr )
565 int	x, y, clr, *oldclr;
566 {
567 register  int	c, mask;
568 register  char	*sptr;
569 
570 	sptr = dispoff + ( ( SCR_HGHT - y - 1 ) * 160 ) + ( x >> 2 );
571 	mask = 0xC0 >> ( x = ( x & 0x0003 ) << 1 );
572 
573 	if ( oldclr )
574 		*oldclr = ( ( *sptr & mask ) >> ( 6 - x ) ) & 0x00FF;
575 
576 	c = clr << ( 6 - x );
577 	if ( clr & 0x0080 ) {
578 		*sptr	     ^= ( mask & c );
579 		*( sptr+80 ) ^= ( mask & c );
580 	} else {
581 		*sptr	     &= ~mask;
582 		*( sptr+80 ) &= ~mask;
583 		*sptr	     |= ( mask & c );
584 		*( sptr+80 ) |= ( mask & c );
585 	}
586 }
587 
588 
589 
590 
591 /*---------------------------------------------------------------------------
592 
593 	Get/set the current screen resolution.	The resolution is never
594 	changed on a monochrome system.  Low-res 16 colour is used on
595 	colour systems, (equivalent to IBM type 4), except in debugging
596 	instances where high-res 4 colour is used. (equivalent to IBM type 6)
597 
598 	On colour systems, the pixel map for each symbol is converted to
599 	optomize video ram updates.  The bit pattern abcdefghijklmnop is
600 	converted to bdfhjlnpacegikmo for all words of all symbols.
601 ---------------------------------------------------------------------------*/
602 
603 
604 
605 
606 get_type()
607 {
608 	return( scrtype = trap14( 4 ) );
609 }
610 
611 
612 
613 set_type( type )
614 int	type;
615 {
616 	if ( type > 2 ) {
617 		if ( scrtype == 2 ) {
618 			type = 2;
619 			dispg = dispgm;
620 			drawpnt = drawpm;
621 			drawsym = drawsm;
622 		} else {
623 			if ( type == 6 )
624 				type = 1;
625 			else
626 				type = 0;
627 			dispg = dispgc;
628 			drawpnt = drawpc;
629 			drawsym = drawsc;
630 			invertsymbols();
631 		}
632 		trap14( 5, -1L, -1L, type );
633 		trap14( 6, palette );
634 	} else {
635 		trap14( 5, -1L, -1L, type );
636 		trap14( 21, 1 );
637 	}
638 }
639 
640 
641 
642 static	invertsymbols()
643 {
644 extern	char	swplnsym[ORIENTS][ANGLES][SYMBYTES];
645 extern	char	swhitsym[HITSYMS][SYMBYTES];
646 extern	char	swbmbsym[BOMBANGS][BOMBBYTES];
647 extern	char	swtrgsym[TARGORIENTS][TARGBYTES];
648 extern	char	swwinsym[WINSIZES][WINBYTES];
649 extern	char	swhtrsym[TARGBYTES];
650 extern	char	swexpsym[EXPLSYMS][EXPBYTES];
651 extern	char	swflksym[FLCKSYMS][FLKBYTES];
652 extern	char	swbrdsym[BIRDSYMS][BRDBYTES];
653 extern	char	swoxsym[OXSYMS][OXBYTES];
654 
655 	invert( swplnsym, ORIENTS*ANGLES*SYMBYTES );
656 	invert( swhitsym, HITSYMS*SYMBYTES	  );
657 	invert( swbmbsym, BOMBANGS*BOMBBYTES	  );
658 	invert( swtrgsym, TARGORIENTS*TARGBYTES   );
659 	invert( swwinsym, WINSIZES*WINBYTES	  );
660 	invert( swhtrsym, TARGBYTES		  );
661 	invert( swexpsym, EXPLSYMS*EXPBYTES	  );
662 	invert( swflksym, FLCKSYMS*FLKBYTES	  );
663 	copy( swbrdsym, spcbirds );
664 	invert( spcbirds, BIRDSYMS*BRDBYTES*2	  );
665 	invert( swoxsym,  OXSYMS*OXBYTES	  );
666 }
667 
668 
669 
670 static	copy( from, to )
671 char	*from, *to;
672 {
673 int	i;
674 
675 	for ( i = 4; i; --i ) {
676 		*to++ = *from++;
677 		*to++ = '\0';
678 	}
679 }
680 
681 
682 
683 static	invert( symbol, bytes )
684 char	*symbol;
685 int	bytes;
686 {
687 register int	c1, c2;
688 register char	*s;
689 int		n;
690 
691 	s = symbol;
692 	for ( n = bytes >> 1; n; --n ) {
693 		c1 = *s;
694 		c2 = *( s + 1 );
695 		*s++ =	( ( c1 << 1 ) & 0x80 )
696 			| ( ( c1 << 2 ) & 0x40 )
697 			| ( ( c1 << 3 ) & 0x20 )
698 			| ( ( c1 << 4 ) & 0x10 )
699 			| ( ( c2 >> 3 ) & 0x08 )
700 			| ( ( c2 >> 2 ) & 0x04 )
701 			| ( ( c2 >> 1 ) & 0x02 )
702 			| ( c2 & 0x01 );
703 		*s++ =	( c1 & 0x80 )
704 			| ( ( c1 << 1 ) & 0x40 )
705 			| ( ( c1 << 2 ) & 0x20 )
706 			| ( ( c1 << 3 ) & 0x10 )
707 			| ( ( c2 >> 4 ) & 0x08 )
708 			| ( ( c2 >> 3 ) & 0x04 )
709 			| ( ( c2 >> 2 ) & 0x02 )
710 			| ( ( c2 >> 1 ) & 0x01 );
711 	}
712 }
713 
714 
715 
716 
717 
718 
719 /*---------------------------------------------------------------------------
720 
721 	External calls to specify current video ram as screen ram or
722 	auxiliary screen area.
723 
724 ---------------------------------------------------------------------------*/
725 
726 
727 
728 
729 setvdisp()
730 {
731 static	char	*videoram = NULL;
732 
733 	if ( !videoram )
734 		videoram = trap14( 3 );
735 	dispoff = videoram;
736 }
737 
738 
739 
740 
741 setadisp()
742 {
743 	dispoff = auxdisp - 0x4000;
744 }
745 