constrained parallax scrolling
[mdlife] / src / part_dna.c
1 #include <stdio.h>
2 #include "sprite.h"
3 #include "vdp.h"
4 #include "demo.h"
5 #include "pad.h"
6 #include "parts.h"
7 #include "debug.h"
8
9 static void particle(int x, int y, int sz);
10
11 #define SPRITE_BASE             0x8000
12 extern uint16_t cellspr_data[], cellspr_data_end[];
13 extern unsigned char cellspr_cmap[], cellspr_cmap_end[];
14
15
16 void dna_init(void)
17 {
18         int i;
19         uint16_t *src;
20         unsigned char *cptr;
21
22         cptr = cellspr_cmap;
23         for(i=0; i<16; i++) {
24                 vdp_setcolor(0, i, i, i, i);
25                 vdp_setcolor(1, i, cptr[0] >> 4, cptr[1] >> 4, cptr[2] >> 4);
26                 cptr += 3;
27         }
28
29         /* upload sprite tiles */
30         src = cellspr_data;
31         vdp_setup_addr(VDP_VRAM, SPRITE_BASE);
32         while(src < cellspr_data_end) {
33                 VDP_DATA = *src++;
34         }
35 }
36
37 void dna_start(void)
38 {
39         short i;
40
41         /* setup tilemaps */
42         vdp_setup_addr(VDP_VRAM, 0xc000);       /* nametable A */
43         for(i=0; i<2048; i++) {
44                 VDP_DATA = 0;
45         }
46         vdp_setup_addr(VDP_VRAM, 0xe000);       /* nametable B */
47         for(i=0; i<2048; i++) {
48                 VDP_DATA = 0;
49         }
50
51         vdp_setup_addr(VDP_VRAM, 0xf000);       /* hscroll table is at f000, see vdp.S */
52         VDP_DATA = 0;
53         VDP_DATA = 0;
54 }
55
56 void dna_update(void)
57 {
58         static int x = 160;
59         static int y = 120;
60         static int sz = 24;
61
62         if(bnstate & PAD_UP) {
63                 if(y > 0) y--;
64         } else if(bnstate & PAD_DOWN) {
65                 if(y < 239) y++;
66         }
67         if(bnstate & PAD_LEFT) {
68                 if(y > 0) x--;
69         } else if(bnstate & PAD_RIGHT) {
70                 if(y < 319) x++;
71         }
72         if(bndiff & bnstate & PAD_A) {
73                 if(sz > 0) sz--;
74         } else if(bndiff & bnstate & PAD_B) {
75                 if(sz < 32) sz++;
76         }
77
78         particle(x, y, sz);
79 }
80
81 static void particle(int x, int y, int pixsz)
82 {
83         int tile, offs = 4, invoffs, szlevel;
84         static int offstab[] = {
85                 4, 4, 4, 4, 4, 4, 4, 4,
86                 4, 8, 8, 8, 8, 8, 8, 8,
87
88                 8, 14, 14, 15, 15, 15, 16, 16,
89                 16, 14, 14, 15, 15, 15, 16, 16,
90                 16
91         };
92
93         dbgval[0] = pixsz;
94
95         if(pixsz <= 2) {
96                 szlevel = 0;
97                 pixsz = 2;
98                 tile = VDP_ADDR2TILE(SPRITE_BASE);
99         } else if(pixsz <= 16) {
100                 szlevel = (pixsz - 1) >> 1;
101                 tile = VDP_ADDR2TILE(SPRITE_BASE) + szlevel;
102         } else if(pixsz <= 24) {
103                 szlevel = 8;
104                 tile = VDP_ADDR2TILE(SPRITE_BASE) + 8;
105         } else if(pixsz <= 32) {
106                 szlevel = 9;
107                 tile = VDP_ADDR2TILE(SPRITE_BASE) + 12;
108         } else {
109                 szlevel = 9;
110                 tile = VDP_ADDR2TILE(SPRITE_BASE) + 12;
111                 pixsz = 32;
112         }
113
114         dbgval[1] = szlevel;
115         dbgval[2] = tile;
116
117         offs = offstab[pixsz];
118
119         switch(szlevel) {
120         case 0:
121         case 1:
122         case 2:
123         case 3:
124                 spr_add(x - offs, y - offs, VDP_TILENAME(tile, 1, VDP_TILE_FG), SPR_SIZE(1, 1));
125                 break;
126
127         case 4: /* 10x10 */
128         case 5: /* 12x12 */
129         case 6: /* 14x14 */
130         case 7: /* 16x16 */
131                 spr_add(x - offs, y - offs, VDP_TILENAME(tile, 1, VDP_TILE_FG), SPR_SIZE(1, 1));
132                 spr_add(x, y - offs, VDP_TILENAME(tile, 1, VDP_TILE_FG | VDP_TILE_HFLIP), SPR_SIZE(1, 1));
133                 spr_add(x - offs, y, VDP_TILENAME(tile, 1, VDP_TILE_FG | VDP_TILE_VFLIP), SPR_SIZE(1, 1));
134                 spr_add(x, y, VDP_TILENAME(tile, 1, VDP_TILE_FG | VDP_TILE_HVFLIP), SPR_SIZE(1, 1));
135                 break;
136
137         case 8: /* 17x17 - 24x24 */
138         default: /* 25x25 - 32x32 */
139                 invoffs = 16 - offs;
140                 spr_add(x - offs, y - offs, VDP_TILENAME(tile, 1, VDP_TILE_FG), SPR_SIZE(2, 2));
141                 spr_add(x - invoffs, y - offs, VDP_TILENAME(tile, 1, VDP_TILE_FG | VDP_TILE_HFLIP), SPR_SIZE(2, 2));
142                 spr_add(x - offs, y - invoffs, VDP_TILENAME(tile, 1, VDP_TILE_FG | VDP_TILE_VFLIP), SPR_SIZE(2, 2));
143                 spr_add(x - invoffs, y - invoffs, VDP_TILENAME(tile, 1, VDP_TILE_FG | VDP_TILE_HVFLIP), SPR_SIZE(2, 2));
144                 break;
145         }
146
147         dbgval[3] = offs;
148 }