1 #include <fcntl.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <sys/time.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <math.h>
8 #include <sys/types.h>
9 
10 #include <SDL.h>
11 #include <SDL_mixer.h>
12 
13 #include "timeless.h"
14 
15 #define XSIZE 640
16 #define YSIZE 400
17 SDL_Surface *thescreen;
18 
19 #define ON_W 400
20 #define ON_H 280
21 
22 int fast=0;
23 
24 unsigned char offscreen[256*256];
25 unsigned char onscreen_buffer[ON_W * ON_H];
26 unsigned char *onscreen = onscreen_buffer + (ON_W-320)/2 + ON_W*((ON_H-200)/2);
27 
28 #define OPTION_UNWARP_BG    1
29 #define OPTION_FAST         2
30 #define OPTION_PAUSED       4
31 
clear(void)32 void clear(void)
33 {
34 	memset(thescreen->pixels,0,XSIZE*YSIZE*2);
35 }
36 
cd(int x,int y,int c)37 void cd(int x,int y,int c)
38 {
39 	*((unsigned short *)thescreen->pixels+y*thescreen->pitch/2+x)=c;
40 }
41 
colordot(int x,int y,int c)42 void colordot(int x, int y, int c)
43 {
44 	x<<=1;
45 	y<<=1;
46 	cd(x,y,c);
47 	cd(x+1,y,c);
48 	cd(x,y+1,c);
49 	cd(x+1,y+1,c);
50 
51 }
52 
scrlock(void)53 void scrlock(void)
54 {
55 	if(SDL_MUSTLOCK(thescreen))
56 	{
57 		if ( SDL_LockSurface(thescreen) < 0 )
58 		{
59 			fprintf(stderr, "Couldn't lock display surface: %s\n",
60 								SDL_GetError());
61 		}
62 	}
63 }
64 
scrunlock(void)65 void scrunlock(void)
66 {
67 	if(SDL_MUSTLOCK(thescreen))
68 		SDL_UnlockSurface(thescreen);
69 	else
70 		SDL_UpdateRect(thescreen, 0, 0, 0, 0);
71 }
72 
maprgb(int r,int g,int b)73 unsigned long maprgb(int r,int g,int b)
74 {
75 	return SDL_MapRGB(thescreen->format,r,g,b);
76 }
77 
78 /*****************************************************
79  *****************************************************
80  Graphics helper functions
81  ****************************************************
82  ****************************************************/
83 
84 unsigned char *d3tile;
85 int d3counter;
86 unsigned char *d8tile;
87 int delaycntr;
88 unsigned char *pal0aptr = pal0a;
89 
90 void r_m00(void);
91 void r_m01(void);
92 void r_m02(void);
93 void r_m03(void);
94 void r_m04(void);
95 void r_m05(void);
96 void r_m06(void);
97 void r_m07(void);
98 void r_m08(void);
99 void r_m09(void);
100 void r_m0a(void);
101 void r_m0b(void);
102 void r_m0c(void);
103 void r_m0d(void);
104 void r_m0e(void);
105 void r_m0f(void);
106 void r_m10(void);
107 void r_m11(void);
108 void r_m12(void);
109 void r_m13(void);
110 void r_m14(void);
111 void r_m15(void);
112 void r_m16(void);
113 
114 void r_p00(void);
115 void r_p10(void);
116 void r_p20(void);
117 void r_p30(void);
118 void r_p40(void);
119 void r_p50(void);
120 void r_p60(void);
121 void r_p70(void);
122 void r_p80(void);
123 void r_p90(void);
124 void waitpals(void);
125 
126 void r_delay(void);
127 void r_fast(void);
128 void r_slow(void);
129 void setnext(void);
130 void setstart(void);
131 void restart(void);
132 
133 void l1start(void);
134 void l2start(void);
135 
136 int l1on=0;
137 int l2on=0;
138 
139 void (*routtbl[])(void)={
140 //r_fast,
141 	r_m00, r_p00, r_m01, r_p10, r_m02, waitpals,
142 	setstart,
143 	r_m03, r_p20, r_m04, waitpals, r_m05,
144 	r_delay, r_p30,
145 	r_m06, r_p30,
146 	r_m07, r_p30,
147 	r_m08, waitpals,
148 	r_p40, r_delay,
149 	r_m09, r_m0a, r_p30, r_delay,
150 	r_p50, r_m0b, r_delay, r_m0c, waitpals,
151 	r_p60, r_m0d,
152 	r_p70, r_delay,
153 	r_m0e, r_p30, r_delay,
154 	r_m0f, r_p80,
155 	r_delay,
156 	r_m10, r_p30, r_m11, r_p30,
157 	r_p90, r_delay, r_m12,
158 	r_p70,
159 	r_m13, r_p20, r_m14, waitpals,
160 	r_p60, r_m15, r_p30, r_delay,
161 	r_m16, r_p30, r_delay,
162 	restart
163 };
164 
165 int routtblindex=0;
166 int routtblstart=0;
167 void (*l0rout)(void) = setnext;
168 void (*l1rout)(void) = l1start;
169 void (*l2rout)(void) = l2start;
170 
setstart(void)171 void setstart(void)
172 {
173 	routtblstart=routtblindex;
174 	setnext();
175 }
176 
restart(void)177 void restart(void)
178 {
179 	routtblindex=routtblstart;
180 	pal0aptr += 64*3;
181 	if(pal0aptr == pal0a + 64*3*6)
182 		pal0aptr = pal0a;
183 	setnext();
184 }
185 
setnext(void)186 void setnext(void)
187 {
188 //printf("next!\n");
189 	l0rout = routtbl[++routtblindex];
190 
191 }
192 
r_delay(void)193 void r_delay(void)
194 {
195 	if(!--delaycntr)
196 		setnext();
197 }
198 
199 
200 /*****************************************************
201  *****************************************************
202  Graphics routines, l0 stuff
203  ****************************************************
204  ****************************************************/
205 
206 // sprite structure:
207 // 1 byte of # of pixels in this strip
208 // x coordinate
209 // y coordinate
210 // 1 byte for each pixel in strip
211 // 0 byte = endmark
drawsprite(unsigned char * dest,unsigned char * sp)212 void drawsprite(unsigned char *dest, unsigned char *sp)
213 {
214 int c;
215 	while((c=*sp))
216 	{
217 		memcpy(dest + sp[1] + sp[2]*400, sp+3, c);
218 		sp+=c+3;
219 	}
220 }
221 
222 // from l0p0.m
r_p00(void)223 void r_p00(void)
224 {
225 static unsigned short loc=0x357c;
226 static unsigned short locd=0x137e;
227 static unsigned char color=0;
228 static unsigned char counter=0;
229 
230 int i;
231 	locd += 0x1395;
232 	for(i=0;i<32;++i)
233 	{
234 		offscreen[loc&0xffff] = color;
235 		color = (color+13) & 0x3f;
236 		if(locd&0x8000)
237 		{
238 			++loc;
239 			locd <<=1;
240 			++locd;
241 		} else
242 			locd<<=1;
243 		loc+=locd;
244 	}
245 	counter -= 2;
246 	if(!counter) setnext();
247 
248 }
249 
250 // from l0p1.m
r_p10(void)251 void r_p10(void)
252 {
253 static unsigned char counter=0;
254 int i;
255 int ax;
256 int bx;
257 
258 	ax=0x40;
259 	bx=counter;
260 	for(i=0;i<16;++i)
261 	{
262 		bx&=0xffff;
263 		offscreen[(bx  )&0xffff] = ax;
264 		offscreen[(bx+1)&0xffff] = ax;
265 		offscreen[(bx+256  )&0xffff] = ax;
266 		offscreen[(bx+257)&0xffff] = ax;
267 		ax += 0x4;
268 		bx += 97*256+97;
269 	}
270 	ax=0x42;
271 	bx = 0x3300 + ((-counter)&255);
272 	for(i=0;i<16;++i)
273 	{
274 		offscreen[(bx  )&0xffff] = ax;
275 		offscreen[(bx+1)&0xffff] = ax;
276 		offscreen[(bx+256  )&0xffff] = ax;
277 		offscreen[(bx+257)&0xffff] = ax;
278 		ax+=0x4;
279 		bx += 17*256+223;
280 	}
281 	ax=0x41;
282 	bx = (counter<<8) | 0x57;
283 	for(i=0;i<16;++i)
284 	{
285 		offscreen[(bx  )&0xffff] = ax;
286 		offscreen[(bx+1)&0xffff] = ax;
287 		offscreen[(bx+256  )&0xffff] = ax;
288 		offscreen[(bx+257)&0xffff] = ax;
289 		ax+=0x4;
290 		bx+=111*256+17;
291 	}
292 	ax=0x43;
293 	bx=(-counter<<8) | 0xa9;
294 	for(i=0;i<16;++i)
295 	{
296 		offscreen[(bx  )&0xffff] = ax;
297 		offscreen[(bx+1)&0xffff] = ax;
298 		offscreen[(bx+256  )&0xffff] = ax;
299 		offscreen[(bx+257)&0xffff] = ax;
300 		ax+=0x4;
301 		bx+=203*256+117;
302 	}
303 
304 	if(!--counter)
305 		setnext();
306 }
307 
308 // from l0p2.m crossing lines, fill whole screen
r_p20(void)309 void r_p20(void)
310 {
311 static unsigned char counter=0;
312 unsigned char al;
313 int i;
314 unsigned char *p;
315 
316 // 80, 81...bf..bf..be...80
317 	al = counter<64 ? counter+0x80 : 0xff-counter;
318 	p=offscreen+counter*2;
319 	for(i=0;i<0x100;++i)
320 		p[i*0x100] = al;
321 	p=offscreen+counter*0x200;
322 	memset(p, al, 256);
323 	p=offscreen+(counter^0x7f)*0x200 + 0x100;
324 	memset(p, al, 256);
325 	p=offscreen+(counter^0x7f)*2 + 1;
326 	for(i=0;i<0x100;++i)
327 		p[i*0x100] = al;
328 	counter = (counter+1) & 0x7f;
329 	if(!counter) setnext();
330 }
331 
332 // from l0p4.m
r_p40(void)333 void r_p40(void)
334 {
335 static unsigned short loc=0x7e7e;
336 static short locd=-2;
337 static unsigned char len=1;
338 static unsigned char lend=1;
339 int color;
340 int i;
341 unsigned short si,di;
342 
343 	color = (0x41 - len) & 0xff;
344 	if(color<0x40)
345 		++color;
346 	color+=0x3f;
347 	di=si=loc;
348 	for(i=0;i<len;++i)
349 	{
350 		offscreen[0xffff & (di+0)] = color;
351 		offscreen[0xffff & (di+1)] = color;
352 		offscreen[0xffff & (si+0)] = color;
353 		offscreen[0xffff & (si+1)] = color;
354 		offscreen[0xffff & (di+256)] = color;
355 		offscreen[0xffff & (di+257)] = color;
356 		offscreen[0xffff & (si+256)] = color;
357 		offscreen[0xffff & (si+257)] = color;
358 		di+=0x202;
359 		si-=0x1fe;
360 	}
361 	if(len!=1)
362 	{
363 		di-=0x400;
364 		si+=0x400;
365 		for(i=1;i<len;++i)
366 		{
367 			offscreen[0xffff & (di+0)] = color;
368 			offscreen[0xffff & (di+1)] = color;
369 			offscreen[0xffff & (si+0)] = color;
370 			offscreen[0xffff & (si+1)] = color;
371 			offscreen[0xffff & (di+256)] = color;
372 			offscreen[0xffff & (di+257)] = color;
373 			offscreen[0xffff & (si+256)] = color;
374 			offscreen[0xffff & (si+257)] = color;
375 			di-=0x1fe;
376 			si+=0x202;
377 		}
378 	}
379 	loc += locd;
380 	len = len + lend;
381 	if(!len)
382 	{
383 		loc = 0x7e7e;
384 		len = 1;
385 		locd = -2;
386 		lend = 1;
387 		setnext();
388 	} else
389 	{
390 		if(len>=0x42)
391 		{
392 			loc=0xfe7e;
393 			len=0x41;
394 			locd=2;
395 			lend=-1;
396 		}
397 	}
398 }
399 
r_p50(void)400 void r_p50(void)
401 {
402 static unsigned char cntr=255;
403 int ebp;
404 int i;
405 int ebx;
406 int dl;
407 int edi;
408 int ah;
409 
410 	edi = cntr<<8;
411 	ebp = cntr & 0x7f;
412 	if(ebp >= 0x40) ebp^=0x7f;
413 	ebp -= 0x20;
414 	dl=0;
415 	for(i=0;i<256;++i)
416 	{
417 		ebx=sincos0s[dl & 0xff] * ebp;
418 		dl+=8;
419 		ebx&=0xff00;
420 		ah = (ebx>>8) + 0xa0;
421 		offscreen[(edi+ebx    ) & 0xffff] = ah;
422 		offscreen[(edi+ebx+256) & 0xffff] = ah;
423 		++edi;
424 	}
425 	if(!cntr--)
426 		setnext();
427 }
428 
r_p60(void)429 void r_p60(void)
430 {
431 static unsigned char loc=0;
432 	memset(offscreen + loc*256, 0, 0x2000);
433 	loc += 0x20;
434 	if(!loc)
435 		setnext();
436 }
437 
r_p70r0(int dest,int sin,int ch)438 int r_p70r0(int dest, int sin, int ch)
439 {
440 int i,j,k;
441 int cl;
442 int di;
443 
444 	for(i=0;i<4;++i)
445 	{
446 		cl=sincos0[sin & 0xff];
447 		sin+=4;
448 		cl>>=3;
449 		di = dest + (ch*256) + cl;
450 		for(j=0;j<15;++j)
451 		{
452 			for(k=0;k<16;++k)
453 				offscreen[(di+k)&0xffff] += 4;
454 			di+=0x100;
455 		}
456 		dest += ch*256;
457 	}
458 	return (dest>>8) & 0xff;
459 }
r_p70(void)460 void r_p70(void)
461 {
462 static unsigned char loc[2]={0,0};
463 static unsigned char sinloc=0;
464 	loc[0] = r_p70r0(loc[0]*256       , sinloc,  1);
465 	loc[1] = r_p70r0(loc[1]*256 + 0x80, sinloc, -1);
466 	sinloc+=16;
467 	if(!loc[1])
468 		setnext();
469 }
470 
r_p80(void)471 void r_p80(void)
472 {
473 static unsigned short loc=0xe000;
474 static unsigned short locd=0x2000;
475 static unsigned short locdtbl[]={
476 	0x2000, 0x20, 0xe000, 0xffe0, 0x2000, 0x20, 0xe000,
477 	0xffe0, 0x2000, 0x20, 0xe000, 0xffe0, 0x2000, 0x20, 0xe000, 0};
478 static unsigned char cntr=8;
479 static unsigned char index=0;
480 static unsigned char cntrtbl[]={8,7,7,6,6,5,5, 4,4,3,3,2,2,1, 1, 1};
481 int i;
482 
483 	loc+=locd;
484 	if(!--cntr)
485 	{
486 		index=(index+1)&15;
487 		cntr=cntrtbl[index];
488 		locd=locdtbl[index];
489 		if(!index)
490 		{
491 			loc=0;
492 			setnext();
493 		}
494 	}
495 	for(i=0;i<32;++i)
496 		memcpy(offscreen+((loc+i*256)&0xffff), d8tile+i*32, 32);
497 }
498 
r_p90(void)499 void r_p90(void)
500 {
501 static unsigned char cntr=0;
502 int delta,color;
503 unsigned char *p;
504 int i;
505 
506 	delta=1;
507 	color = cntr & 0x7f;
508 	if(color&0x40) {color^=0x7f;delta=-1;}
509 	p=offscreen + cntr*256;
510 	for(i=0;i<4;++i)
511 	{
512 		memset(p, color, 256);
513 		p+=256;
514 		color+=delta;
515 	}
516 	if(!(cntr+=4))
517 		setnext();
518 }
519 
520 
521 // scale factors = 32 = 1:1 scale, 64 = 2:1 scale, 16 = 1:2 scale, etc.
scaletile(unsigned short dest,unsigned char * src,int xscale,int yscale)522 void scaletile(unsigned short dest, unsigned char *src, int xscale, int yscale)
523 {
524 int x,y;
525 unsigned short dp;
526 int tx,ty;
527 int px,py;
528 unsigned char *sp, c;
529 	++xscale;
530 	++yscale;
531 	px = (32<<16) / xscale;
532 	py = (32<<16) / yscale;
533 
534 	ty = py>>1;
535 	for(y=0;y<yscale;++y)
536 	{
537 		dp = dest+y*256;
538 		sp = src + 32*(ty>>16);
539 		tx = px>>1;
540 		for(x=0;x<xscale;++x)
541 		{
542 			dest&=0xffff;
543 			c=sp[tx>>16];
544 			if(c)
545 				offscreen[dp] = c;
546 			++dp;
547 			tx += px;
548 		}
549 		ty += py;
550 	}
551 }
552 
553 // from l0p3.m growing 4 bitmaps at rnd locs
r_p30(void)554 void r_p30(void)
555 {
556 static unsigned short d3loc=0x53c7;
557 static unsigned short d3locd=0x137e;
558 static unsigned char d3size=0;
559 static unsigned char d3counter2=4;
560 static unsigned char d3sizetbl[]={4,4,4,4, 5,5,6,7};
561 static unsigned int d3sizeseed=0x974adec2;
562 int size, scale;
563 int t;
564 
565 	size = 255 & (1<<d3size++);
566 	scale = size-1;
567 
568 	scaletile(d3loc-size*256 - size, d3tile       , scale, scale);
569 	scaletile(d3loc-size*256       , d3tile + 1024, scale, scale);
570 	scaletile(d3loc          - size, d3tile + 2048, scale, scale);
571 	scaletile(d3loc                , d3tile + 3072, scale, scale);
572 
573 	if(!--d3counter2)
574 	{
575 		d3locd += 0x4377;
576 		d3locd = (d3locd<<5) | (d3locd>>11);
577 		d3loc = t = d3loc + d3locd + (d3locd & 1);
578 		d3sizeseed += d3loc;
579 		if(t&0x10000) ++d3sizeseed;
580 		d3sizeseed = (d3sizeseed<<9) | (d3sizeseed>>23);
581 		d3counter2 = d3sizetbl[d3sizeseed & 7];
582 		d3size = 0;
583 		if(!--d3counter) setnext();
584 
585 /*
586 		t=(d3locd + 0x4377);
587 		t = (t<<5) | ((t&0xffff)>>11);
588 		d3locd = t;
589 		d3loc += t;
590 		if(t&0x10000)
591 			++d3loc;
592 		if(t>0xffff)
593 			t=(t&0xffff) + d3sizeseed+1;
594 		else
595 			t+=d3sizeseed;
596 		t=((t&0x7ff) << 5) | ((t&0xf800)>>11);
597 		d3sizeseed=t;
598 		d3counter2=d3sizetbl[t&7];
599 		d3size=0;
600 		if(!--d3counter) setnext();
601 */
602 	}
603 }
604 
605 
606 /*****************************************************
607  *****************************************************
608  Graphics routines, l1 stuff
609  ****************************************************
610  ****************************************************/
611 
612 void r_l1p00(void);
613 void r_l1p10(void);
614 void r_l1p20(void);
615 void r_l1p30(void);
616 void r_l1p40(void);
617 void r_l1p50(void);
618 void r_l1p60(void);
619 void r_l1p70(void);
620 void r_l1p80(void);
621 void r_l1p90(void);
622 void r_l1restart(void);
623 void l1setnext(void);
624 
625 void (*l1routtbl[])(void)={
626  r_l1p00, r_l1p10, r_l1p20, r_l1p30, r_l1p40,
627  r_l1p60, r_l1p70, r_l1p80, r_l1p50, r_l1p90,
628  r_l1p00, r_l1p20, r_l1p30, r_l1p40, r_l1p60,
629  r_l1p50, r_l1p10, r_l1p80, r_l1p70, r_l1p90,
630  r_l1p30, r_l1p40, r_l1p50, r_l1p60, r_l1p00,
631  r_l1p80, r_l1p10, r_l1p20, r_l1p90, r_l1p70,
632  r_l1restart
633 };
634 
635 int l1index=0;
636 
r_l1restart(void)637 void r_l1restart(void)
638 {
639 	l1index=0;
640 	l1setnext();
641 }
642 
l1setnext(void)643 void l1setnext(void)
644 {
645 	l1rout = l1routtbl[l1index++];
646 }
647 
648 
649 // from l1p0.m, rolling daisy
r_l1p00(void)650 void r_l1p00(void)
651 {
652 static unsigned char *csprtbl[] =
653 	{cspr02,cspr01,cspr00};
654 static int csprloctbl[]={400*168+320, 400*200, -32, 400*-32+288};
655 static short csprdtbl[]={-4, -1600, 4, 1600};
656 static unsigned char csprcntrtbl[]={88,58,88,58};
657 static int csprloc=400*168+320;
658 static short csprd=-4;
659 static unsigned char csprindex=0;
660 static unsigned char csprcntr=88;
661 static unsigned char csprnexti=0;
662 	csprloc += csprd;
663 	if(!csprindex--) csprindex=2;
664 	drawsprite(onscreen + csprloc, csprtbl[csprindex]);
665 	if(!--csprcntr)
666 	{
667 		csprnexti = (csprnexti+1)&3;
668 		csprloc = csprloctbl[csprnexti];
669 		csprd = csprdtbl[csprnexti];
670 		csprcntr = csprcntrtbl[csprnexti];
671 		l1setnext();
672 	}
673 }
674 
675 // from l1p1.m, fishies
r_l1p10(void)676 void r_l1p10(void)
677 {
678 static unsigned char *fishframetbl[] =
679 	{cspr03,cspr04};
680 static unsigned int fishseed=0x974adec2;
681 static unsigned short fishx[]={0,0,0,0,0,0,0,0,0,0};
682 static unsigned short fishy[]={0,0,0,0,0,0,0,0,0,0};
683 static unsigned char fishframe[]={0,0,0,0,0,0,0,0,0,0};
684 static int fishyaddtbl[]={-400,0,0,400};
685 static unsigned char fishendcntr=10;
686 static unsigned char fishinitcntr=10;
687 static unsigned char fishinitcntr2=1;
688 int i,t;
689 unsigned char *dest=onscreen - 5*4, *edi;
690 unsigned int ecx;
691 int edx;
692 	ecx = fishseed;
693 	for(i=9;i>=0;ecx+=i,--i)
694 	{
695 		t=fishx[i]-3;
696 		if(t>=0)
697 		{
698 			fishx[i]=t;
699 			if(t==0)
700 			{
701 				if(!--fishendcntr)
702 				{
703 					fishendcntr=10;
704 					fishinitcntr=10;
705 					l1setnext();
706 					return;
707 				}
708 				continue;
709 			}
710 			fishframe[i]^=1;
711 			edi = dest + t;
712 			edx = fishy[i] + fishyaddtbl[ecx&3];
713 			if(edx>=0 && edx<=183*400)
714 				fishy[i] = edx;
715 			edi += edx;
716 			drawsprite(edi, fishframetbl[fishframe[i]]);
717 			ecx = (ecx>>11) | (ecx<<21);
718 			if(ecx & (1<<31))
719 				++ecx;
720 			ecx += 0x12345671;
721 		}
722 	}
723 	if(fishinitcntr && !--fishinitcntr2)
724 	{
725 		--fishinitcntr;
726 		fishinitcntr2=(ecx&15) + 4;
727 		fishx[fishinitcntr]=342;
728 		fishy[fishinitcntr]=(((ecx>>8)&0x7f)+27)*400;
729 		ecx = (ecx>>5) | (ecx<<27);
730 		if(ecx & (1<<31))
731 			++ecx;
732 		ecx += 0x59f4132f;
733 	}
734 	fishseed = ecx;
735 
736 }
737 
738 // from l1p2.m, slug
r_l1p20(void)739 void r_l1p20(void)
740 {
741 static unsigned char *sluggycsprtbl[] =
742 	{cspr06,cspr07,cspr08,cspr07,cspr06,cspr05};
743 static unsigned char sluggyframe=5;
744 static int sluggyy=233;
745 static unsigned char sluggyx=0x71;
746 static unsigned char sluggyofftbl[]={9,5,0,0,0,0};
747 unsigned char *dest;
748 
749 	dest=onscreen + (sluggyy-sluggyofftbl[sluggyframe]) * ON_W + sluggyx;
750 	dest += -29*ON_W + 6;
751 	drawsprite(dest, sluggycsprtbl[sluggyframe]);
752 
753 	if(!sluggyframe--)
754 	{
755 		sluggyframe=5;
756 		if(sluggyy>=13)
757 			sluggyy-=13;
758 		else
759 		{
760 			sluggyy=233;
761 			sluggyx+=0x6f;
762 			l1setnext();
763 		}
764 	}
765 }
766 
767 // from l1p3.m, happy faces
r_l1p30(void)768 void r_l1p30(void)
769 {
770 static unsigned int happyseed=0x9693972e;
771 static unsigned short happyloc[16]={0};
772 static unsigned char happyindex=0;
773 static short happymloc=-40;
774 int i;
775 int eax;
776 int ecx;
777 
778 	for(i=15;i>=0;--i)
779 		drawsprite(onscreen + happyloc[i], cspr09);
780 
781 	happyindex=(happyindex+1)&15;
782 	eax = (happyseed & 0x3f) + happymloc;
783 	if(eax<0 || eax>=320) eax=320;
784 	ecx = (happyseed >> 6) & 255;
785 	if(ecx >= 200-12) ecx -= 156;
786 	happyloc[happyindex] = ecx*400 + eax;
787 	happyseed = (happyseed >> 9) | (happyseed << 23);
788 	happyseed += 0x123457 + happyindex;
789 	happymloc += 7;
790 	if(happymloc >= 320+7*16)
791 	{
792 		happymloc = -40;
793 		l1setnext();
794 	}
795 }
796 
797 // from l1p4.m
p40r0a(unsigned short * loc,int * x,int * y)798 int p40r0a(unsigned short *loc, int *x, int *y)
799 {
800 	*x=*y=0;
801 	*loc += 2;
802 	if(*loc>=50)
803 	{
804 		*x = 131+(sincos0[*loc & 255]>>1);
805 		*y = *loc - 50;
806 	}
807 	return 0;
808 }
p40r0b(unsigned short * loc,int * x,int * y)809 int p40r0b(unsigned short *loc, int *x, int *y)
810 {
811 	*x=*y=0;
812 	if(*loc==276) return 1;
813 	if(*loc >= 226) return 0;
814 
815 	*x = 131 + sincos0[(*loc - 50 + 0x80)&0xff];
816 	*y = *loc;
817 	return 0;
818 }
819 
p40r1a(unsigned short * loc,int * x,int * y)820 int p40r1a(unsigned short *loc, int *x, int *y)
821 {
822 	*x=*y=0;
823 	*loc += 3;
824 	if(*loc < 80) return 0;
825 
826 	*x = *loc - 80;
827 	*y = 49+(sincos0[*x & 0xff]>>1);
828 	return 0;
829 }
p40r1b(unsigned short * loc,int * x,int * y)830 int p40r1b(unsigned short *loc, int *x, int *y)
831 {
832 	*x=*y=0;
833 	if(*loc >= 472) return 1;
834 	if(*loc >= 392) return 0;
835 	*x = *loc;
836 	*y = 49 + (sincos0[(*x - 80 - 0x80)&0xff]>>1);
837 	return 0;
838 }
839 
p40r2a(unsigned short * loc,int * x,int * y)840 int p40r2a(unsigned short *loc, int *x, int *y)
841 {
842 	*x=*y=0;
843 	*loc += 2;
844 	if(*loc >= 50)
845 	{
846 		*y = *loc - 50;
847 		*x = 131 + (sincos0[(*y - 50 - 0x80)&0xff]>>1);
848 		*y = 226 - *y;
849 	}
850 
851 	return 0;
852 }
p40r2b(unsigned short * loc,int * x,int * y)853 int p40r2b(unsigned short *loc, int *x, int *y)
854 {
855 	*x=*y=0;
856 	if(*loc == 276) return 1;
857 	if(*loc >= 226) return 0;
858 	*x = 131 + (sincos0[(*loc - 50 - 0x80)&0xff]>>1);
859 	*y = 224 - *loc;
860 	return 0;
861 }
p40r3a(unsigned short * loc,int * x,int * y)862 int p40r3a(unsigned short *loc, int *x, int *y)
863 {
864 	*x=*y=0;
865 	*loc += 3;
866 	if(*loc < 78) return 0;
867 	*x = *loc - 78;
868 	*y = 49 + (sincos0[*x & 255]>>1);
869 	*x = 396 - *x;
870 
871 	return 0;
872 }
p40r3b(unsigned short * loc,int * x,int * y)873 int p40r3b(unsigned short *loc, int *x, int *y)
874 {
875 	*x=*y=0;
876 	if(*loc == 474) return 1;
877 	if(*loc >= 396) return 0;
878 	*y = 49 + (sincos0[(*loc - 78 - 0x80)&0xff]>>1);
879 	*x = 393 - *loc;
880 	return 0;
881 }
882 
r_l1p40(void)883 void r_l1p40(void)
884 {
885 static int (*posrouttbl[2][8])(unsigned short *loc, int *x, int *y)={
886 	{p40r0a, p40r1a, p40r2a, p40r3a, p40r0a, p40r1a, p40r2a, p40r3a },
887 	{p40r0b, p40r1b, p40r2b, p40r3b, p40r0b, p40r1b, p40r2b, p40r3b }};
888 static unsigned char *wingframe[]=
889 	{cspr0b,cspr0c,cspr0d,cspr0c};
890 static unsigned char *centercsprtbl[]={cspr0a,cspr17,cspr11,cspr10,cspr22};
891 static unsigned short loc;
892 static unsigned char frame[2]={0,2};
893 static unsigned char posroutindex=0;
894 static unsigned char centercspri=0;
895 int i, res, x=160, y=100;
896 unsigned char *dest;
897 
898 	for(i=0;i<2;++i)
899 	{
900 		res=posrouttbl[i][posroutindex](&loc, &x, &y);
901 		frame[i] = (frame[i]+1)&3;
902 		dest = onscreen + (y-26)*ON_W + x-18*4;
903 		drawsprite(dest, wingframe[frame[i]]);
904 		drawsprite(dest + 9*ON_W + 6*4, centercsprtbl[centercspri]);
905 		if(i==1 && res)
906 		{
907 			posroutindex = (posroutindex+1) & 7;
908 			loc = 0;
909 			++centercspri;
910 			if(centercspri == 5)
911 				centercspri = 0;
912 			l1setnext();
913 		}
914 	}
915 }
916 
917 // from l1p5.m
r_l1p50(void)918 void r_l1p50(void)
919 {
920 static unsigned char *cspr=cspr0e;
921 static unsigned char *csprtbl[]=
922 	{cspr0e,cspr0f,cspr12,cspr13,cspr14,cspr15};
923 static unsigned short csprloc=372;
924 static unsigned char csprindex=0;
925 static unsigned char heighttbl[]={
926 	37,36,36,35,34,33,33,32,31,30,30,29,28,28,27,26,
927 	26,25,24,24,23,23,22,21,21,20,20,19,18,18,17,17,
928 	16,16,15,15,14,14,13,13,12,12,11,11,10,10,10,9,
929 	9,8,8,8,7,7,6,6,6,5,5,5,5,4,4,4,
930 	3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,0,
931 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
932 	0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,
933 	1,1,2,2,2,2,2,3,3,3,3,4,4,4,5,5,
934 	5,5,6,6,6,7,7,8,8,8,9,9,10,10,10,11,
935 	11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,
936 	20,20,21,21,22,23,23,24,24,25,26,26,27,28,28,29,
937 	30,30,31,32,33,33,34,35,36,36,37
938 };
939 
940 	csprloc-=2;
941 	if(!csprloc)
942 	{
943 		++csprindex;
944 		if(csprindex==6)
945 			csprindex=0;
946 		cspr = csprtbl[csprindex];
947 		csprloc = 372;
948 		l1setnext();
949 	}
950 	drawsprite(onscreen + heighttbl[csprloc>>1]*400 + csprloc + 15*400 - 13*4,
951 		 cspr);
952 }
953 
954 // from l1p6.m
r_l1p60(void)955 void r_l1p60(void)
956 {
957 static int locs0[64*2];
958 static int locs1[32*2];
959 static int locs2[16*2];
960 static int first=1;
961 static unsigned char cntr = 0xf0;
962 static unsigned char num=0;
963 static unsigned char numd=1;
964 int temp0, temp1, temp2, temp3;
965 int i;
966 int *p;
967 int ah;
968 int t;
969 	if(first)
970 	{
971 		temp0=0;
972 		temp1=79;
973 		temp2=0;
974 		temp3=67*4+1;
975 		p=locs0;
976 		for(i=0;i<64;++i)
977 		{
978 			*p++ = temp0; // y
979 			*p++ = temp2; // x
980 			temp0 = temp0 + temp1;
981 			if(temp0 > 199)
982 			{
983 				temp0 = temp0 - 200;
984 				temp1 = temp1 - 3;
985 			}
986 			temp2 = temp2 + temp3;
987 			if(temp2 > 319)
988 			{
989 				temp2 = temp2 - 320;
990 				temp3 = temp3 - 16;
991 			}
992 		}
993 
994 		temp0=56;
995 		temp1=95;
996 		temp2=49*4;
997 		temp3=59*4+2;
998 		p=locs1;
999 		for(i=0;i<32;++i)
1000 		{
1001 			*p++ = temp0; // y
1002 			*p++ = temp2; // x
1003 			temp0 = temp0 + temp1;
1004 			if(temp0 > 199)
1005 			{
1006 				temp0 = temp0 - 200;
1007 				temp1 = temp1 - 6;
1008 			}
1009 			temp2 = temp2 + temp3;
1010 			if(temp2 > 319)
1011 			{
1012 				temp2 = temp2 - 320;
1013 				temp3 = temp3 - 20;
1014 			}
1015 		}
1016 
1017 		temp0=132;
1018 		temp1=96;
1019 		temp2=13*4;
1020 		temp3=73*4;
1021 		p=locs2;
1022 		for(i=0;i<16;++i)
1023 		{
1024 			*p++ = temp0; // y
1025 			*p++ = temp2; // x
1026 			temp0 = temp0 + temp1;
1027 			if(temp0 > 199)
1028 			{
1029 				temp0 = temp0 - 200;
1030 				temp1 = temp1 - 8;
1031 			}
1032 			temp2 = temp2 + temp3;
1033 			if(temp2 > 319)
1034 			{
1035 				temp2 = temp2 - 320;
1036 				temp3 = temp3 - 7*4;
1037 			}
1038 		}
1039 		first = 0;
1040 	}
1041 
1042 	if(!--cntr)
1043 	{
1044 		cntr = 0xf0;
1045 		num = 0;
1046 		numd = 1;
1047 		l1setnext();
1048 		return;
1049 	}
1050 	if(cntr == 0x10)
1051 		numd = -1;
1052 	num += numd;
1053 	if(num==0 || num>=0x10)
1054 		numd=0;
1055 
1056 	ah = 0xc7;
1057 	for(i=0;i<16;++i)
1058 	{
1059 		p = locs2 + i*2;
1060 		*p += 4;
1061 		if(*p >= 200)
1062 			*p -= 200;
1063 		p[1]-=4;
1064 		if(p[1]<0)
1065 			p[1] += 320;
1066 		if(i<num)
1067 		{
1068 			t = p[0]*ON_W + p[1];
1069 			memset(onscreen+t+1, ah, 2);
1070 			memset(onscreen+ON_W*3+t+1, ah, 2);
1071 			memset(onscreen+t+ON_W, ah, 4);
1072 			memset(onscreen+t+ON_W*2, ah, 4);
1073 		}
1074 	}
1075 	for(i=0;i<32;++i)
1076 	{
1077 		p = locs1 + i*2;
1078 		*p += 2;
1079 		if(*p >= 200)
1080 			*p -= 200;
1081 		p[1]-=2;
1082 		if(p[1]<0)
1083 			p[1] += 320;
1084 		if(i<num*2)
1085 		{
1086 			t = p[0]*ON_W + p[1];
1087 			onscreen[t]=ah;
1088 			onscreen[t+1]=ah;
1089 			onscreen[t+ON_W]=ah;
1090 			onscreen[t+1+ON_W]=ah;
1091 		}
1092 	}
1093 	for(i=0;i<64;++i)
1094 	{
1095 		p = locs0 + i*2;
1096 		(*p)++;
1097 		if(*p >= 200)
1098 			*p -= 200;
1099 		--p[1];
1100 		if(p[1]<0)
1101 			p[1]+=320;
1102 		if(i<num*4)
1103 			onscreen[p[0]*ON_W + p[1]] = ah;
1104 	}
1105 }
1106 
1107 // from l1p7.m
r_l1p70(void)1108 void r_l1p70(void)
1109 {
1110 static unsigned char *csprtbl[3]={cspr16,cspr0a,cspr17};
1111 static unsigned char eccx=0x40, eccy=0x40;
1112 static unsigned char eccdx = 0xff, eccdy = 0xff;
1113 static unsigned char cspri = 0;
1114 static unsigned char ecccntr = 3;
1115 static int x=0;
1116 static int xd = 2;
1117 static unsigned char phase = 0;
1118 unsigned char *d;
1119 int i;
1120 int tx, ty;
1121 	x += xd;
1122 	if(x==0 || x>=470)
1123 	{
1124 		xd = -xd;
1125 		++cspri;
1126 		if(cspri == 2)
1127 			cspri = 0;
1128 		l1setnext();
1129 		return;
1130 	}
1131 	eccy += eccdy;
1132 	if(eccy < 0x10 ||  eccy >= 0x40)
1133 		eccdy = -eccdy;
1134 	if(!--ecccntr)
1135 	{
1136 		ecccntr = 3;
1137 		eccx += eccdx;
1138 		if(eccx < 0x10 || eccx >= 0x40)
1139 			eccdx = -eccdx;
1140 	}
1141 	d = onscreen + (0x40 - eccy) * ON_W;
1142 	phase+=5;
1143 	for(i=0;i<8;++i)
1144 	{
1145 		ty = (sincos0[(phase + i*32) & 0xff] * eccy) >> 7;
1146 		tx = x + ((sincos0[(phase + i*32 + 0x40) & 0xff] * eccx) >> 7);
1147 		tx -= 128;
1148 		if(tx<0 || tx>=340) continue;
1149 		drawsprite(d + (ty+26)*ON_W + tx - 20, csprtbl[cspri]);
1150 	}
1151 
1152 
1153 }
1154 
1155 // from l1p8.m
r_l1p80(void)1156 void r_l1p80(void)
1157 {
1158 static int locs0[64*2];
1159 static int locs1[32*2];
1160 static int locs2[16*2];
1161 static int first=1;
1162 static unsigned char cntr=0xf0;
1163 static unsigned char num=0, numd=1;
1164 unsigned char ah;
1165 
1166 int *p,i,j;
1167 int t;
1168 
1169 	if(first)
1170 	{
1171 		int temp0, temp1, temp2, temp3;
1172 		temp0=192;
1173 		temp1=188;
1174 		temp2=53*4;
1175 		temp3=37*4;
1176 		p=locs0;
1177 		for(i=0;i<64;++i)
1178 		{
1179 			*p++ = temp0; // y
1180 			*p++ = temp2; // x
1181 			temp0 = temp0 + temp1;
1182 			if(temp0 > 199)
1183 			{
1184 				temp0 = temp0 - 200;
1185 				temp1 = temp1 - 8;
1186 			}
1187 			temp2 = temp2 + temp3;
1188 			if(temp2 > 319)
1189 			{
1190 				temp2 = temp2 - 320;
1191 				temp3 = temp3 - 7*4;
1192 			}
1193 		}
1194 
1195 		temp0=64;
1196 		temp1=96;
1197 		temp2=25*4;
1198 		temp3=31*4+2;
1199 		p=locs1;
1200 		for(i=0;i<32;++i)
1201 		{
1202 			*p++ = temp0; // y
1203 			*p++ = temp2*2; // x
1204 			temp0 = temp0 + temp1;
1205 			if(temp0 > 199)
1206 			{
1207 				temp0 = temp0 - 200;
1208 				temp1 = temp1 - 8;
1209 			}
1210 			temp2 = temp2 + temp3;
1211 			if(temp2 > 159)
1212 			{
1213 				temp2 = temp2 - 160;
1214 				temp3 = temp3 - 3*4;
1215 			}
1216 		}
1217 
1218 		temp0=132;
1219 		temp1=96;
1220 		temp2=13*4;
1221 		temp3=13*4;
1222 		p=locs2;
1223 		for(i=0;i<16;++i)
1224 		{
1225 			*p++ = temp0; // y
1226 			*p++ = temp2*4; // x
1227 			temp0 = temp0 + temp1;
1228 			if(temp0 > 199)
1229 			{
1230 				temp0 = temp0 - 200;
1231 				temp1 = temp1 - 8;
1232 			}
1233 			temp2 = temp2 + temp3;
1234 			if(temp2 > 79)
1235 			{
1236 				temp2 = temp2 - 80;
1237 				temp3 = temp3 - 2*4;
1238 			}
1239 		}
1240 		first = 0;
1241 	}
1242 	if(!--cntr)
1243 	{
1244 		cntr = 0xf0;
1245 		num=0;
1246 		numd=1;
1247 		l1setnext();
1248 		return;
1249 	}
1250 	if(cntr == 0x10)
1251 		numd = -1;
1252 	num += numd;
1253 	if(num==0 || num==0x10)
1254 		numd = 0;
1255 	ah = 0xd9;
1256 	for(i=0;i<16;++i)
1257 	{
1258 		p=locs2 + i*2;
1259 		p[0] += 16;
1260 		if(p[0]>=208)
1261 			p[0] -= 200;
1262 		p[1] -= 16;
1263 		if(p[1]<0)
1264 			p[1] += 320;
1265 		if(i<num)
1266 		{
1267 			t = p[0]*ON_W + p[1];
1268 			for(j=0;j<16;++j)
1269 				onscreen[t - j*(ON_W - 1)] = ah;
1270 		}
1271 	}
1272 
1273 	for(i=0;i<32;++i)
1274 	{
1275 		p=locs1 + i*2;
1276 		p[0] += 8;
1277 		if(p[0] >= 204)
1278 			p[0] -= 200;
1279 		p[1] -= 8;
1280 		if(p[1]<0)
1281 			p[1] += 320;
1282 		if(i<num*2)
1283 		{
1284 			t = p[0]*ON_W + p[1];
1285 			for(j=0;j<8;++j)
1286 				onscreen[t - j*(ON_W - 1)] = ah;
1287 		}
1288 	}
1289 
1290 	for(i=0;i<32;++i)
1291 	{
1292 		p=locs0 + i*2;
1293 		p[0] += 4;
1294 		if(p[0] >= 202)
1295 			p[0] -= 200;
1296 		p[1] -= 4;
1297 		if(p[1]<0)
1298 			p[1] += 320;
1299 		if(i<num*4)
1300 		{
1301 			t = p[0]*ON_W + p[1];
1302 			for(j=0;j<4;++j)
1303 				onscreen[t - j*(ON_W - 1)] = ah;
1304 		}
1305 	}
1306 }
1307 
1308 // from l1p9.m
r_l1p90(void)1309 void r_l1p90(void)
1310 {
1311 static unsigned char *frametbl[]={
1312 	cspr18,cspr19,cspr19,cspr1a,cspr1a,cspr1b,cspr1b,cspr1c,
1313 	cspr1d,cspr1e,cspr1e,cspr1f,cspr1f,cspr20,cspr20,cspr21};
1314 static unsigned short leafx[24];
1315 static unsigned short leafy[24];
1316 static unsigned char dphase[2]={0,0};
1317 static unsigned char cntr=0xf0;
1318 static unsigned char num=0;
1319 static unsigned char numd=1;
1320 
1321 static int first=1;
1322 int i;
1323 
1324 	if(first)
1325 	{
1326 		int temp0, temp1;
1327 		temp0 = 152;
1328 		temp1 = 187;
1329 		for(i=0;i<24;++i)
1330 		{
1331 			leafx[i] = temp0;
1332 			temp0 += temp1;
1333 			if(temp0 > 333)
1334 			{
1335 				temp0 -= 334;
1336 				temp1 -= 17;
1337 			}
1338 		}
1339 
1340 		temp0 = 137;
1341 		temp1 = 167;
1342 		for(i=0;i<24;++i)
1343 		{
1344 			leafy[i] = temp0;
1345 			temp0 += temp1;
1346 			if(temp0 > 209)
1347 			{
1348 				temp0 -= 210;
1349 				temp1 -= 11;
1350 			}
1351 		}
1352 
1353 		first = 0;
1354 	}
1355 
1356 	if(!--cntr)
1357 	{
1358 		cntr = 0xf0;
1359 		num = 0;
1360 		numd = 1;
1361 		for(i=0;i<8;++i)
1362 		{
1363 			unsigned char *tp;
1364 			tp = frametbl[i];
1365 			frametbl[i] = frametbl[i+8];
1366 			frametbl[i+8] = tp;
1367 		}
1368 		l1setnext();
1369 		return;
1370 	}
1371 	if(cntr == 23)
1372 		numd = -1;
1373 	num += numd;
1374 	if(!num || num==23)
1375 		numd = 0;
1376 	dphase[0] += 7;
1377 	dphase[1] += 13;
1378 
1379 	for(i=num;i>=0;--i)
1380 	{
1381 		int t, tx, ty;
1382 
1383 		ty = (sincos0[(dphase[0] + leafy[i])&0xff]>>6) + 1;
1384 		ty = leafy[i] + ty;
1385 		if(ty >= 210) ty-=210;
1386 		leafy[i] = ty;
1387 
1388 		t = sincos0[(dphase[1] + ty)&0xff]>>5;
1389 		tx = (t>>1) + 1;
1390 		tx = leafx[i] - tx;
1391 		if(tx < 0) tx += 334;
1392 		leafx[i] = tx;
1393 		drawsprite(onscreen + (ty-9)*ON_W + tx - 13, frametbl[t]);
1394 	}
1395 
1396 
1397 
1398 }
1399 
1400 
l1start(void)1401 void l1start(void)
1402 {
1403 	if(l1on)
1404 		l1setnext();
1405 }
1406 
1407 
1408 /*****************************************************
1409  *****************************************************
1410  Graphics routines, l2 stuff
1411  ****************************************************
1412  ****************************************************/
1413 
l2start(void)1414 void l2start(void)
1415 {
1416 }
1417 
1418 
1419 /*****************************************************
1420  *****************************************************
1421  Palette related helper functions
1422  ****************************************************
1423  ****************************************************/
1424 
1425 unsigned char thepal[256*3];
1426 unsigned char wantpal[256*3];
1427 
1428 #define COLOROUT(r,g,b) {*p++=r; *p++=g; *p++=b;}
palinit(void)1429 void palinit(void)
1430 {
1431 unsigned char *p;
1432 int temp,i;
1433 	p=pal00; // white
1434 	for(i=temp=0;i<64;++i)
1435 		COLOROUT(temp, temp, temp++)
1436 	for(i=0;i<63;++i)
1437 		COLOROUT(--temp, temp, temp)
1438 
1439 	p=pal01; // blue
1440 	for(i=temp=0;i<64;++i)
1441 		COLOROUT(0, 0, temp++)
1442 	--temp;
1443 	for(i=0;i<63;++i)
1444 		COLOROUT(0, 0, --temp)
1445 
1446 
1447 	p=pal02; // green
1448 	for(i=temp=0;i<64;++i)
1449 		COLOROUT(0, temp++, 0)
1450 	--temp;
1451 	for(i=0;i<63;++i)
1452 		COLOROUT(0, --temp, 0)
1453 
1454 	p=pal03; // red
1455 	for(i=temp=0;i<64;++i)
1456 		COLOROUT(temp++, 0, 0)
1457 	--temp;
1458 	for(i=0;i<63;++i)
1459 		COLOROUT(--temp, 0, 0)
1460 
1461 	p=pal04; // light blue
1462 	for(i=temp=0;i<64;++i)
1463 		COLOROUT(0, temp/2, temp++)
1464 	--temp;
1465 	for(i=0;i<63;++i)
1466 		COLOROUT(0, --temp/2, temp)
1467 
1468 	p=pal05; // light green
1469 	for(i=temp=0;i<64;++i)
1470 		COLOROUT(temp/2, temp++, 0)
1471 	--temp;
1472 	for(i=0;i<63;++i)
1473 		COLOROUT(--temp/2, temp, 0)
1474 
1475 	p=pal06; // magenta
1476 	for(i=temp=0;i<64;++i)
1477 		COLOROUT(temp, 0, temp++/2)
1478 	--temp;
1479 	for(i=0;i<63;++i)
1480 		COLOROUT(--temp, 0, temp/2)
1481 
1482 	p=pal07; // blue/purple
1483 	for(i=temp=0;i<32;++i)
1484 		COLOROUT(0, 0, temp++*2)
1485 	for(i=temp=0;i<32;++i)
1486 		COLOROUT(temp++*2, 0, 63)
1487 	--temp;
1488 	for(i=0;i<31;++i)
1489 		COLOROUT(--temp*2, 0, 63)
1490 	for(i=0,temp=32;i<32;++i)
1491 		COLOROUT(0, 0, --temp*2)
1492 
1493 	p=pal08; // green/light cyan
1494 	for(i=temp=0;i<32;++i)
1495 		COLOROUT(0, temp++*2, 0)
1496 	for(i=temp=0;i<32;++i)
1497 		COLOROUT(0, 63, temp++*2)
1498 	--temp;
1499 	for(i=0;i<31;++i)
1500 		COLOROUT(0, 63, --temp*2)
1501 	for(i=0,temp=32;i<32;++i)
1502 		COLOROUT(0, --temp*2, 0)
1503 
1504 	p=pal09; // red/yellow
1505 	for(i=temp=0;i<32;++i)
1506 		COLOROUT(temp++*2, 0, 0)
1507 	for(i=temp=0;i<32;++i)
1508 		COLOROUT(63, temp++*2, 0)
1509 	--temp;
1510 	for(i=0;i<31;++i)
1511 		COLOROUT(63, --temp*2, 0)
1512 	for(i=0,temp=32;i<32;++i)
1513 		COLOROUT(--temp*2, 0, 0)
1514 
1515 	p=pal0b; // violet
1516 	for(i=temp=0;i<64;++i)
1517 		COLOROUT(temp/2, 0, temp++)
1518 	--temp;
1519 	for(i=0;i<63;++i)
1520 		COLOROUT(--temp/2, 0, temp)
1521 
1522 	p=pal0c; // blue green
1523 	for(i=temp=0;i<64;++i)
1524 		COLOROUT(0, temp, temp++/2)
1525 	--temp;
1526 	for(i=0;i<63;++i)
1527 		COLOROUT(0, --temp, temp/2)
1528 
1529 	p=pal0d; // orange
1530 	for(i=temp=0;i<64;++i)
1531 		COLOROUT(temp, temp++/2, 0)
1532 	--temp;
1533 	for(i=0;i<63;++i)
1534 		COLOROUT(--temp, temp/2, 0)
1535 
1536 	p=pal0e; // blue/white
1537 	for(i=temp=0;i<32;++i)
1538 		COLOROUT(0, 0, temp++*2)
1539 	for(i=temp=0;i<32;++i)
1540 		COLOROUT(temp*2, temp++*2, 63)
1541 	--temp;
1542 	for(i=0;i<31;++i)
1543 		COLOROUT(--temp*2, temp*2, 63)
1544 	for(i=0,temp=32;i<32;++i)
1545 		COLOROUT(0, 0, --temp*2)
1546 
1547 	p=pal0f; // green/white
1548 	for(i=temp=0;i<32;++i)
1549 		COLOROUT(0, temp++*2, 0)
1550 	for(i=temp=0;i<32;++i)
1551 		COLOROUT(temp*2, 63, temp++*2)
1552 	--temp;
1553 	for(i=0;i<31;++i)
1554 		COLOROUT(--temp*2, 63, temp*2)
1555 	for(i=0,temp=32;i<32;++i)
1556 		COLOROUT(0, --temp*2, 0)
1557 
1558 	p=pal10; // red/white
1559 	for(i=temp=0;i<32;++i)
1560 		COLOROUT(temp++*2, 0, 0)
1561 	for(i=temp=0;i<32;++i)
1562 		COLOROUT(63, temp*2, temp++*2)
1563 	--temp;
1564 	for(i=0;i<31;++i)
1565 		COLOROUT(63, --temp*2, temp*2)
1566 	for(i=0,temp=32;i<32;++i)
1567 		COLOROUT(--temp*2, 0, 0)
1568 
1569 //	memcpy(thepal+192*3, pal0aptr, 64*3);
1570 }
1571 
1572 int palindex=0;
1573 
1574 unsigned char *palptrtbl[]={
1575 	pal02, pal00,pal01,pal06,pal09,pal01,pal07,pal04,pal03,
1576 	pal05,pal0e,pal0d,pal0c,pal0b,pal03,
1577 	pal01,pal0f,pal10,pal04,pal08,pal0b
1578 };
1579 
1580 #define PALTBLLEN (sizeof(palptrtbl)/sizeof(palptrtbl[0]))
1581 
1582 int slidewhich=-1;
1583 int slidelen;
1584 unsigned char *slidetake;
1585 
doslide(void)1586 void doslide(void)
1587 {
1588 unsigned char *s, *d;
1589 int i,j;
1590 int delta;
1591 
1592 	if(slidewhich>=0)
1593 	{
1594 		delta = 1;
1595 		s=slidetake;
1596 		d=thepal+slidewhich*3;
1597 		for(i=j=0;i<slidelen*3;++i)
1598 		{
1599 			if(*s<*d)
1600 			{
1601 				if(*d -1 == *s)
1602 					--*d;
1603 				else
1604 					*d -= delta;
1605 				++j;
1606 			}
1607 			else if(*s>*d)
1608 			{
1609 				if(*d +1 == *s)
1610 					++*d;
1611 				else
1612 					*d += delta;
1613 				++j;
1614 			}
1615 			++s;
1616 			++d;
1617 		}
1618 		if(!j)
1619 			slidewhich=-1;
1620 	}
1621 }
1622 
waitpals(void)1623 void waitpals(void)
1624 {
1625 	if(slidewhich<0)
1626 	{
1627 		setnext();
1628 	}
1629 }
1630 
nextpal(int n,int slide)1631 void nextpal(int n, int slide)
1632 {
1633 unsigned char *put;
1634 	if(++palindex == PALTBLLEN)
1635 		palindex=0;
1636 //printf("nextpal %d, index %d\n", n, palindex);
1637 	put = slide ? wantpal : thepal;
1638 	memcpy(put+n*64*3, palptrtbl[palindex], 64*3);
1639 	if(slide)
1640 	{
1641 		slidewhich=n*64;
1642 		slidelen=64;
1643 		slidetake = wantpal + n*64*3;
1644 	}
1645 }
1646 
set_pals(int n,int len,unsigned char * pal)1647 void set_pals(int n, int len, unsigned char *pal)
1648 {
1649 	slidelen=len;
1650 	slidewhich=n;
1651 	slidetake = pal;
1652 }
1653 
set_pal(int n,int len,unsigned char * pal)1654 void set_pal(int n, int len, unsigned char *pal)
1655 {
1656 	memcpy(thepal + n*3, pal, len*3);
1657 }
1658 
1659 /*****************************************************
1660  *****************************************************
1661  Palette related routines
1662  ****************************************************
1663  ****************************************************/
r_m00(void)1664 void r_m00(void)
1665 {
1666 	nextpal(0,1);
1667 	setnext();
1668 }
1669 
r_m01(void)1670 void r_m01(void)
1671 {
1672 	nextpal(1,1);
1673 	setnext();
1674 }
1675 
r_m02(void)1676 void r_m02(void)
1677 {
1678 	set_pals(0,64,_bpal);
1679 	setnext();
1680 }
1681 
r_m03(void)1682 void r_m03(void)
1683 {
1684 	nextpal(2,1);
1685 	setnext();
1686 }
1687 
r_m04(void)1688 void r_m04(void)
1689 {
1690 	set_pals(192,64, pal0aptr);
1691 	nextpal(1,0);
1692 	setnext();
1693 }
1694 
r_m05(void)1695 void r_m05(void)
1696 {
1697 	nextpal(2,1);
1698 	d3tile = gradient_sphere;
1699 	d3counter = 0x10;
1700 	delaycntr = 2;
1701 	setnext();
1702 }
1703 
r_m06(void)1704 void r_m06(void)
1705 {
1706 	l1on=1;
1707 	set_pals(128, 64, _bpal);
1708 	d3counter = 0x20;
1709 	setnext();
1710 }
1711 
r_m07(void)1712 void r_m07(void)
1713 {
1714 	d3tile = daisy;
1715 	d3counter = 0x40;
1716 	setnext();
1717 }
1718 
r_m08(void)1719 void r_m08(void)
1720 {
1721 	nextpal(1,1);
1722 	delaycntr=0x80;
1723 	setnext();
1724 }
1725 
r_m09(void)1726 void r_m09(void)
1727 {
1728 	nextpal(2,0);
1729 	nextpal(1,1);
1730 	setnext();
1731 }
1732 
r_m0a(void)1733 void r_m0a(void)
1734 {
1735 	d3tile = lightning;
1736 	d3counter = 0x10;
1737 	delaycntr = 0x40;
1738 	setnext();
1739 }
1740 
r_m0b(void)1741 void r_m0b(void)
1742 {
1743 	delaycntr = 0x40;
1744 	setnext();
1745 }
1746 
r_m0c(void)1747 void r_m0c(void)
1748 {
1749 	set_pals(0,192,_bpal);
1750 	setnext();
1751 }
1752 
r_m0d(void)1753 void r_m0d(void)
1754 {
1755 	nextpal(0,0);
1756 	delaycntr = 0x40;
1757 	setnext();
1758 }
1759 
r_m0e(void)1760 void r_m0e(void)
1761 {
1762 	nextpal(1,0);
1763 	d3tile = star_thingy;
1764 	d3counter = 0x10;
1765 	delaycntr = 0x40;
1766 	setnext();
1767 }
1768 
r_m0f(void)1769 void r_m0f(void)
1770 {
1771 	nextpal(2,0);
1772 	d8tile = small_gradient_sphere;
1773 	delaycntr=0x40;
1774 	setnext();
1775 }
1776 
r_m10(void)1777 void r_m10(void)
1778 {
1779 	d3tile=eyeball;
1780 	d3counter=0x10;
1781 	setnext();
1782 }
1783 
r_m11(void)1784 void r_m11(void)
1785 {
1786 	nextpal(0,0);
1787 	set_pals(128,64,_bpal);
1788 	d3counter=0x40;
1789 	delaycntr=0x40;
1790 	setnext();
1791 }
1792 
r_m12(void)1793 void r_m12(void)
1794 {
1795 	set_pals(64, 64, palptrtbl[palindex]+63*3);
1796 	setnext();
1797 }
1798 
r_m13(void)1799 void r_m13(void)
1800 {
1801 	nextpal(2,0);
1802 	setnext();
1803 }
1804 
r_m14(void)1805 void r_m14(void)
1806 {
1807 	set_pal(0, 64, _bpal);
1808 	set_pals(128, 64, _bpal);
1809 	setnext();
1810 }
1811 
r_m15(void)1812 void r_m15(void)
1813 {
1814 	nextpal(0,1);
1815 	d3tile = face;
1816 	d3counter=0x20;
1817 	delaycntr=0x80;
1818 	setnext();
1819 }
1820 
r_m16(void)1821 void r_m16(void)
1822 {
1823 	d3tile = sundial;
1824 	d3counter=0x10;
1825 	delaycntr=0x40;
1826 	setnext();
1827 }
1828 
1829 struct mover {
1830 	int at;
1831 	int moving;
1832 	int delaycount;
1833 	int delayperiod;
1834 	int which;
1835 	int wants[8];
1836 };
stepmover(struct mover * m)1837 int stepmover(struct mover *m)
1838 {
1839 	if(!m->moving)
1840 	{
1841 		if(!--m->delaycount)
1842 		{
1843 			m->which=(m->which+1) & 7;
1844 			m->delaycount = m->delayperiod;
1845 			m->moving=1;
1846 		}
1847 	} else
1848 	{
1849 		int want=m->wants[m->which];
1850 		if(m->at < want)
1851 			++m->at;
1852 		else if(m->at > want)
1853 			--m->at;
1854 		else
1855 			m->moving=0;
1856 	}
1857 	return m->at;
1858 }
1859 
1860 /*****************************************************
1861  *****************************************************
1862  Generate the bg scan table algorithmically instead of as data
1863  ****************************************************
1864  ****************************************************/
1865 
init_gnbgtbl(void)1866 void init_gnbgtbl(void)
1867 {
1868 int i,j;
1869 double a;
1870 unsigned char *p;
1871 double f;
1872 double rtab[256];
1873 
1874 	for(i=0;i<100;++i)
1875 	{
1876 		f=i;
1877 		rtab[i] = 256*99.0 / (16*99 - 15*f); // 3d projection approach
1878 //		rtab[i] = (15.8891 + .0512321*f)/(1.0-.00926684*f); // Approx. Tran's
1879 	}
1880 
1881 	p=gnbgtbl;
1882 	for(i=0;i<320;++i)
1883 	{
1884 #define PI 3.14159265358979323846264338327950288
1885 		a = i*(PI/160.0);
1886 		for(j=0;j<100;++j)
1887 		{
1888 			*p++ = rtab[j]*sin(a); // y
1889 			*p++ = rtab[j]*cos(a); // x
1890 		}
1891 	}
1892 	for(i=0;i<320;++i)
1893 	{
1894 		int atx, aty;
1895 		int wx, wy;
1896 
1897 		p=gnbgtbl + i*200;
1898 		atx=aty=0;
1899 		for(j=0;j<100;++j)
1900 		{
1901 			wy = p[0];
1902 			wx = p[1];
1903 			*p++ = wy-aty;
1904 			*p++ = wx-atx;
1905 			atx=wx;
1906 			aty=wy;
1907 		}
1908 	}
1909 }
1910 
1911 
1912 /*****************************************************
1913  *****************************************************
1914  Draw the warped background
1915  ****************************************************
1916  ****************************************************/
1917 
gnbg(void)1918 void gnbg(void)
1919 {
1920 int x,y,c;
1921 static unsigned char *skewptr=gnbgtbl;		// ptr to row to skew
1922 static unsigned short skewcounter=0x10f;	// counter between skewing
1923 static unsigned char skewmode=0;			// 0=wait, 1=skewing
1924 static unsigned char skewindex=3;
1925 static int skewtbl[]={1,-3,5,-3};
1926 int eax;
1927 int i;
1928 static struct mover mtblvpdir={5,0,0xe7,0xf0,0,{5,-7,6,-5,9,-6,7,-9}};
1929 static struct mover mtblvpy={3,0,0xc0,0xc0,0, {3,-1,5,-3,1,-5,1,-3}};
1930 static struct mover mtblvpx={1,0,0x60,0xc0,0, {1,-5,1,-3,3,-1,5,-3}};
1931 
1932 static int vpdir=0;		// viewpoint direction (0-319)
1933 static unsigned short vploc=0x8080;	// viewpoint loc, Y*256+X
1934 unsigned char *bp;
1935 
1936 #if 1
1937 	if(skewmode)
1938 	{
1939 		eax = skewtbl[skewindex];
1940 		for(i=0;i<320;++i)
1941 			skewptr[i*200] += eax;
1942 		skewptr+=2;
1943 		if(skewptr == gnbgtbl+200)
1944 		{
1945 			skewptr = gnbgtbl;
1946 			skewmode=0;
1947 		}
1948 
1949 	} else if(!--skewcounter)
1950 	{
1951 		skewcounter=0x175;
1952 		skewmode=1;
1953 		skewindex=(skewindex+1) & 3;
1954 	}
1955 
1956 // do movement on X and Y
1957 	i=stepmover(&mtblvpy);
1958 	vploc += (i<<8);
1959 	i=stepmover(&mtblvpx);
1960 	vploc = (vploc&0xff00) | ((vploc+i)&0xff);
1961 // do direction spin
1962 	vpdir += stepmover(&mtblvpdir);
1963 	if(vpdir<0) vpdir+=320;
1964 	if(vpdir>=320) vpdir-=320;
1965 #endif
1966 	bp=gnbgtbl + 200*vpdir;
1967 	for(x=0;x<320;++x)
1968 	{
1969 		unsigned char sx, sy;
1970 		sx = vploc>>8;
1971 		sy = vploc;
1972 
1973 		for(y=0;y<100;++y)
1974 		{
1975 			sy += *bp++;
1976 			sx += *bp++;
1977 			c=offscreen[(sx<<8) | sy++];
1978 			onscreen[x+y*ON_W]=c;
1979 			onscreen[x+(199-y)*ON_W]=c;
1980 		}
1981 		if(bp==gnbgtbl + 64000)
1982 			bp=gnbgtbl;
1983 	}
1984 }
1985 
gnbg2(void)1986 void gnbg2(void)
1987 {
1988 int y;
1989 unsigned char *p=offscreen;
1990 unsigned char *d;
1991 	for(y=0;y<256;++y)
1992 	{
1993 		d=onscreen+(y-28)*ON_W;
1994 		memset(d, 0, 32);
1995 		memcpy(d + 32, p+y*256, 256);
1996 		memset(d + 32 + 256, 0, 32);
1997 	}
1998 }
1999 
r_fast(void)2000 void r_fast(void)
2001 {
2002 	fast=1;
2003 	setnext();
2004 }
2005 
r_slow(void)2006 void r_slow(void)
2007 {
2008 	fast=0;
2009 	setnext();
2010 }
2011 
iterate(Uint32 interval,void * flagp)2012 Uint32 iterate(Uint32 interval, void *flagp)
2013 {
2014 int i;
2015 unsigned char *p;
2016 int x,y;
2017 unsigned int map[256];
2018 int flags = *(int *)flagp;
2019 int n;
2020 	if(fast || (flags & OPTION_FAST))
2021 		n = 8;
2022 	else
2023 		n = 1;
2024 	if(flags & OPTION_PAUSED)
2025 		n = 0;
2026 	while(n--)
2027 	{
2028 		doslide();
2029 		p=thepal;
2030 		for(i=0;i<256;++i)
2031 		{
2032 			map[i]=maprgb(p[0]*4, p[1]*4, p[2]*4);
2033 			p+=3;
2034 		}
2035 		if(flags & OPTION_UNWARP_BG)
2036 			gnbg2();
2037 		else
2038 			gnbg();
2039 		l0rout();
2040 		l1rout();
2041 		l2rout();
2042 	}
2043 
2044 	scrlock();
2045 	for(y=0;y<200;++y)
2046 	{
2047 		p=onscreen + y*ON_W;
2048 		for(x=0;x<320;++x)
2049 			colordot(x, y, map[*p++]);
2050 	}
2051 	scrunlock();
2052 	return interval;
2053 }
2054 
general_init(void)2055 void general_init(void)
2056 {
2057 	init_gnbgtbl();
2058 	palinit();
2059 	l0rout = routtbl[0];
2060 }
2061 
main(int argc,char ** argv)2062 int main(int argc,char **argv)
2063 {
2064 int code;
2065 int mousex,mousey;
2066 int done=0;
2067 SDL_Event event;
2068 unsigned int videoflags=0;
2069 int flags=0;
2070 
2071 	struct _Mix_Music* music;
2072 	SDL_Init(SDL_INIT_AUDIO);
2073 	Mix_OpenAudio(MIX_DEFAULT_FREQUENCY,
2074                 MIX_DEFAULT_FORMAT,
2075                 MIX_DEFAULT_CHANNELS, 512);
2076 
2077 	music = Mix_LoadMUS(DATADIR "/time.s3m");
2078 
2079 	if (!music) {
2080 		printf("Music Failed To Load");
2081 	}
2082 
2083 	Mix_PlayMusic(music, -1);
2084 
2085 	printf("SDL Timeless version 1.00\n");
2086 
2087 	if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0 )
2088 	{
2089 		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
2090 		exit(1);
2091 	}
2092 
2093 	videoflags = SDL_FULLSCREEN;
2094 	thescreen = SDL_SetVideoMode(XSIZE, YSIZE, 16, videoflags);
2095 	if ( thescreen == NULL )
2096 	{
2097 		fprintf(stderr, "Couldn't set display mode: %s\n",
2098 							SDL_GetError());
2099 		exit(5);
2100 	}
2101 
2102 	SDL_ShowCursor(0);
2103 
2104 	general_init();
2105 	SDL_AddTimer(40, iterate, &flags);
2106 	while(!done)
2107 	{
2108 		usleep(20000);
2109 		while(SDL_PollEvent(&event))
2110 		{
2111 			switch(event.type)
2112 			{
2113 			case SDL_MOUSEMOTION:
2114 				mousex=event.motion.x;
2115 				mousey=event.motion.y;
2116 				break;
2117 			case SDL_MOUSEBUTTONDOWN:
2118 				break;
2119 			case SDL_KEYDOWN:
2120 				code=event.key.keysym.sym;
2121 				if(code==SDLK_ESCAPE) done=1;
2122 				if(code==SDLK_SPACE) flags ^= OPTION_PAUSED;
2123 				if(code=='1') flags ^= OPTION_UNWARP_BG;
2124 				if(code=='f') flags |= OPTION_FAST;
2125 				break;
2126 			case SDL_KEYUP:
2127 				code=event.key.keysym.sym;
2128 				if(code=='f') flags &= ~OPTION_FAST;
2129 				break;
2130 			}
2131 		}
2132 	}
2133 
2134 	Mix_FadeOutMusic(2000);
2135 
2136 	while(Mix_PlayingMusic()) {
2137 		SDL_Delay(100);
2138 	}
2139 
2140 	Mix_HaltMusic();
2141 	Mix_FreeMusic(music);
2142 	music=NULL;
2143 
2144 	SDL_ShowCursor(1);
2145 
2146 	SDL_Quit();
2147 	return 0;
2148 }
2149 
2150