72697434a1fee13b380855cc4b77f9487c2d1ce1
[gbajam22] / src / logoscr.c
1 #include "gbaregs.h"
2 #include "game.h"
3 #include "gba.h"
4 #include "dma.h"
5 #include "sprite.h"
6 #include "util.h"
7 #include "xgl.h"
8 #include "polyfill.h"
9 #include "timer.h"
10 #include "input.h"
11 #include "data.h"
12 #include "meshdata.h"
13 #include "debug.h"
14
15 static int logoscr_start(void);
16 static void logoscr_stop(void);
17 static void logoscr_frame(void);
18 static void logoscr_vblank(void);
19
20 static struct screen logoscr = {
21         "logo",
22         logoscr_start,
23         logoscr_stop,
24         logoscr_frame,
25         logoscr_vblank
26 };
27
28 static uint16_t *framebuf;
29 static int nframes, backbuf;
30 static uint16_t *vram[] = { gba_vram_lfb0, gba_vram_lfb1 };
31
32 static int nfaces;
33 static struct { int32_t x, y; } *pos;
34
35 #define MAX_SPR 4
36 static uint16_t oam[4 * MAX_SPR];
37
38 static int16_t sprmat[4];
39
40
41 struct screen *init_logo_screen(void)
42 {
43         return &logoscr;
44 }
45
46
47 static int logoscr_start(void)
48 {
49         int i;
50         unsigned int sprflags;
51
52         gba_setmode(4, DISPCNT_BG2 | DISPCNT_OBJ);
53
54         gba_bgpal[0] = 0;
55         gba_bgpal[0xff] = 0xffff;
56
57         xgl_viewport(0,  0, 240, 160);
58
59         nfaces = sizeof logomesh / sizeof *logomesh / 3;
60         pos = malloc_nf(nfaces * sizeof *pos);
61
62         for(i=0; i<nfaces; i++) {
63                 pos[i].x = (rand() & 0xffff) - 0x8000;
64                 pos[i].y = (rand() & 0xffff) - 0x8000;
65                 pos[i].x += pos[i].x << 4;
66                 pos[i].y += pos[i].y << 4;
67         }
68
69         spr_setup(16, 8, spr_logo_pixels, spr_logo_cmap);
70         /* setup blank glint palette */
71         for(i=0; i<192; i++) {
72                 gba_objpal[i + 64] = 0xffff;
73         }
74
75         REG_BLDCNT = BLDCNT_DARKEN | BLDCNT_A_OBJ;
76         REG_BLDY = 0;
77         sprflags = SPR_SZ64 | SPR_HRECT | SPR_256COL | SPR_DBLSZ | SPR_ROTSCL | SPR_ROTSCL_SEL(0);
78         spr_oam(oam, 0, SPRID(0, 0), 24-32, 125-16, sprflags);
79         spr_oam(oam, 1, SPRID(64, 0), 64+24-32, 125-16, sprflags);
80         spr_oam(oam, 2, SPRID(0, 32), 128+24-32, 125-16, sprflags);
81
82         sprmat[0] = sprmat[3] = 0x100;
83         sprmat[1] = sprmat[2] = 0;
84         spr_transform(oam, 0, sprmat);
85
86         nframes = 0;
87         reset_msec_timer();
88         return 0;
89 }
90
91 static void logoscr_stop(void)
92 {
93         REG_BLDCNT = 0;
94         REG_BLDY = 15;
95 }
96
97 static int32_t tm, tgoat, tname, tout;
98
99 #define end_screen()    change_screen(find_screen("menu")); return
100
101 static void logoscr_frame(void)
102 {
103         int i;
104         struct xvertex *vptr;
105         int32_t x, y;
106
107         update_keyb();
108
109         if(KEYPRESS(BN_START)) {
110                 end_screen();
111         }
112
113         tgoat = 0x10000 - tm;
114         if(tgoat < 0) tgoat = 0;
115
116         if(tm > 0x20000) {
117                 tout = (tm - 0x20000) * 5 / 3;
118
119                 if(tout > X_HPI + 0x1800) {
120                         tout = X_HPI + 0x1800;
121                         end_screen();
122                 }
123         }
124
125         backbuf = ++nframes & 1;
126         framebuf = vram[backbuf];
127
128         polyfill_framebuffer(framebuf, 240, 160);
129         fillblock_16byte(framebuf, 0, 240 * 160 / 16);
130
131         xgl_load_identity();
132         xgl_scale(0x10000, 0xcccc, 0x10000);
133         xgl_translate(0, 0, (14 << 16) - (tout << 2));
134         xgl_rotate_x(-X_HPI);
135         xgl_rotate_y(tout);
136         xgl_rotate_z(tout);
137
138         xgl_index(0xff);
139         vptr = logomesh;
140         for(i=0; i<nfaces; i++) {
141
142                 x = (pos[i].x * (tgoat >> 8)) >> 8;
143                 y = (pos[i].y * (tgoat >> 8)) >> 8;
144
145                 xgl_push_matrix();
146                 xgl_translate(x, 0, y);
147                 xgl_draw(XGL_TRIANGLES, vptr, 3);
148                 xgl_pop_matrix();
149
150                 vptr += 3;
151         }
152
153         wait_vblank();
154         present(backbuf);
155 }
156
157 ARM_IWRAM
158 static void logoscr_vblank(void)
159 {
160         tm = timer_msec << 5;
161
162         tname = 0x10000 - (tm - 0x10000);
163         if(tname < 0) tname = 0;
164         if(tname > 0x10000) tname = 0x10000;
165
166         REG_BLDY = tname >> 12;
167
168         if(tm > 0x20000) {
169                 if(sprmat[0] > 0) {
170                         sprmat[0] -= 2;
171                 }
172                 spr_transform(oam, 0, sprmat);
173                 REG_BLDY = (0x100 - sprmat[0]) >> 4;
174                 REG_BLDCNT = BLDCNT_DARKEN | BLDCNT_A_OBJ | BLDCNT_A_BG2;
175         }
176
177         dma_copy32(3, (void*)OAM_ADDR, oam, MAX_SPR * 2, 0);
178 }