add missing tools/pngdump to the repo
[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         srand(0);
63         for(i=0; i<nfaces; i++) {
64                 pos[i].x = (rand() & 0xffff) - 0x8000;
65                 pos[i].y = (rand() & 0xffff) - 0x8000;
66                 pos[i].x += pos[i].x << 4;
67                 pos[i].y += pos[i].y << 4;
68         }
69         pos[57].x = -0x40000;
70         pos[57].y = 0x20000;
71
72         spr_setup(16, 8, spr_logo_pixels, spr_logo_cmap);
73         /* setup blank glint palette */
74         for(i=0; i<192; i++) {
75                 gba_objpal[i + 64] = 0xffff;
76         }
77
78         REG_BLDCNT = BLDCNT_DARKEN | BLDCNT_A_OBJ;
79         REG_BLDY = 0;
80         sprflags = SPR_SZ64 | SPR_HRECT | SPR_256COL | SPR_DBLSZ | SPR_ROTSCL | SPR_ROTSCL_SEL(0);
81         spr_oam(oam, 0, SPRID(0, 0), 24-32, 125-16, sprflags);
82         spr_oam(oam, 1, SPRID(64, 0), 64+24-32, 125-16, sprflags);
83         spr_oam(oam, 2, SPRID(0, 32), 128+24-32, 125-16, sprflags);
84
85         sprmat[0] = sprmat[3] = 0x100;
86         sprmat[1] = sprmat[2] = 0;
87         spr_transform(oam, 0, sprmat);
88
89         nframes = 0;
90         return 0;
91 }
92
93 static void logoscr_stop(void)
94 {
95         REG_BLDCNT = 0;
96         REG_BLDY = 15;
97 }
98
99 static int32_t tm, tgoat, tname, tout;
100
101 #define end_screen()    change_screen(find_screen("menu")); return
102
103 static void logoscr_frame(void)
104 {
105         int i;
106         struct xvertex *vptr;
107         int32_t x, y;
108
109         update_keyb();
110
111         if(KEYPRESS(BN_START)) {
112                 end_screen();
113         }
114
115         tgoat = 0x10000 - tm;
116         if(tgoat < 0) tgoat = 0;
117
118         if(tm > 0x20000) {
119                 tout = (tm - 0x20000) * 5 / 3;
120
121                 if(tout > X_HPI + 0x1800) {
122                         tout = X_HPI + 0x1800;
123                         end_screen();
124                 }
125         }
126
127         backbuf = ++nframes & 1;
128         framebuf = vram[backbuf];
129
130         polyfill_framebuffer(framebuf, 240, 160);
131         fillblock_16byte(framebuf, 0, 240 * 160 / 16);
132
133         xgl_load_identity();
134         xgl_scale(0x10000, 0xcccc, 0x10000);
135         xgl_translate(0, 0, (14 << 16) - (tout << 2));
136         xgl_rotate_x(-X_HPI);
137         xgl_rotate_y(tout);
138         xgl_rotate_z(tout);
139
140         xgl_index(0xff);
141         vptr = logomesh;
142         for(i=0; i<nfaces; i++) {
143
144                 x = (pos[i].x * (tgoat >> 8)) >> 8;
145                 y = (pos[i].y * (tgoat >> 8)) >> 8;
146
147                 xgl_push_matrix();
148                 xgl_translate(x, 0, y);
149                 xgl_draw(XGL_TRIANGLES, vptr, 3);
150                 xgl_pop_matrix();
151
152                 vptr += 3;
153         }
154
155         wait_vblank();
156         present(backbuf);
157 }
158
159 ARM_IWRAM
160 static void logoscr_vblank(void)
161 {
162         tm = timer_msec << 5;
163
164         tname = 0x10000 - (tm - 0x10000);
165         if(tname < 0) tname = 0;
166         if(tname > 0x10000) tname = 0x10000;
167
168         REG_BLDY = tname >> 12;
169
170         if(tm > 0x20000) {
171                 if(sprmat[0] > 0) {
172                         sprmat[0] -= 2;
173                 }
174                 spr_transform(oam, 0, sprmat);
175                 REG_BLDY = (0x100 - sprmat[0]) >> 4;
176                 REG_BLDCNT = BLDCNT_DARKEN | BLDCNT_A_OBJ | BLDCNT_A_BG2;
177         }
178
179         dma_copy32(3, (void*)OAM_ADDR, oam, MAX_SPR * 2, 0);
180 }