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