f927ceee9a093b89704f9f28493be6eacee0a553
[gbajam21] / src / gamescr.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include "gbaregs.h"
4 #include "dma.h"
5 #include "data.h"
6 #include "util.h"
7 #include "intr.h"
8 #include "input.h"
9 #include "debug.h"
10
11 static void draw_tunnel(void);
12
13 static int nframes, backbuf;
14 static uint16_t *vram[] = { (uint16_t*)VRAM_LFB_FB0_ADDR, (uint16_t*)VRAM_LFB_FB1_ADDR };
15 static unsigned char *tex;
16 static uint16_t bnstate;
17
18 void gamescr(void)
19 {
20         int i;
21         uint16_t *cdst;
22         unsigned char *csrc;
23
24         REG_DISPCNT = 4 | DISPCNT_BG2 | DISPCNT_FB1;
25
26         vblperf_setcolor(0xff);
27
28         cdst = (uint16_t*)CRAM_BG_ADDR;
29         csrc = tuncross_cmap;
30         for(i=0; i<256; i++) {
31                 *cdst++ = CONV_RGB24_RGB15(csrc[0], csrc[1], csrc[2]);
32                 csrc += 3;
33         }
34
35         fillblock_16byte(vram[0], 0xffffffff, 240 * 160 / 16);
36         fillblock_16byte(vram[1], 0xffffffff, 240 * 160 / 16);
37
38         tex = iwram_sbrk(32 * 32);
39         memcpy(tex, tuncross_pixels, 32 * 32);
40
41         select_input(BN_DPAD);
42
43         nframes = 0;
44         for(;;) {
45                 backbuf = ++nframes & 1;
46
47                 bnstate = get_input();
48
49                 draw_tunnel();
50
51                 vblperf_end();
52                 wait_vblank();
53                 present(backbuf);
54                 vblperf_begin();
55         }
56 }
57
58 __attribute__((noinline, target("arm"), section(".iwram")))
59 static void draw_tunnel(void)
60 {
61         static int uoffs;
62         int i, j, tx, ty, angle, depth, zoffs;
63         uint16_t pptop, ppbot;
64         uint16_t *top, *bot;
65         uint32_t tun, *tunptr;
66
67         zoffs = nframes;
68
69         if(bnstate & BN_LEFT) uoffs++;
70         if(bnstate & BN_RIGHT) uoffs--;
71
72         top = vram[backbuf];
73         bot = vram[backbuf] + 159 * 240 / 2;
74         tunptr = tunmap;
75         for(i=0; i<80; i++) {
76 #ifdef VBLBAR
77                 top++;
78                 bot++;
79                 tunptr++;
80
81                 for(j=1; j<240/2; j++) {
82 #else
83                 for(j=0; j<240/2; j++) {
84 #endif
85                         tun = *tunptr++;
86
87                         angle = tun & 0xff;
88                         depth = (tun >> 8) & 0xff;
89                         tx = ((angle >> 1) + uoffs) & 0x1f;
90                         ty = ((depth >> 1) + zoffs) & 0x1f;
91                         pptop = tex[(ty << 5) + tx];
92                         tx = ~((angle >> 1) - uoffs) & 0x1f;
93                         ppbot = tex[(ty << 5) + tx];
94
95                         angle = (tun >> 16) & 0xff;
96                         depth = (tun >> 24) & 0xff;
97                         tx = ((angle >> 1) + uoffs) & 0x1f;
98                         ty = ((depth >> 1) + zoffs) & 0x1f;
99                         pptop |= (uint16_t)tex[(ty << 5) + tx] << 8;
100                         tx = ~((angle >> 1) - uoffs) & 0x1f;
101                         ppbot |= (uint16_t)tex[(ty << 5) + tx] << 8;
102
103                         *top++ = pptop;
104                         *bot++ = ppbot;
105                 }
106                 bot -= 240;
107         }
108 }