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