11 #include "cgmath/cgmath.h"
13 #define TM_RIPPLE_START 1.0f
14 #define TM_RIPPLE_TRANS_LEN 3.0f
17 #define HFOV (VFOV * 1.333333f)
19 static int init(void);
20 static void destroy(void);
21 static void start(long trans_time);
22 static void draw(void);
23 static void draw_mountains(void);
25 static struct screen scr = {
34 static float cam_theta = 0, cam_phi = 0;
35 static float cam_dist = 0;
37 static struct g3d_mesh gmesh;
38 #define GMESH_GRIDSZ 25
39 #define GMESH_SIZE 128
40 static struct image gtex;
42 #define MOUNTIMG_WIDTH 512
43 #define MOUNTIMG_HEIGHT 64
44 static struct image mountimg;
45 static int mountimg_skip[MOUNTIMG_WIDTH];
47 static long part_start;
50 struct screen *cybersun_screen(void)
59 if(gen_plane_mesh(&gmesh, GMESH_SIZE, GMESH_SIZE, GMESH_GRIDSZ, GMESH_GRIDSZ) == -1) {
62 for(i=0; i<gmesh.vcount; i++) {
63 gmesh.varr[i].u *= GMESH_GRIDSZ;
64 gmesh.varr[i].v *= GMESH_GRIDSZ;
66 if(load_image(>ex, "data/pgrid.png") == -1) {
69 if(load_image(&mountimg, "data/cybmount.png") == -1) {
72 assert(mountimg.width == MOUNTIMG_WIDTH);
73 assert(mountimg.height == MOUNTIMG_HEIGHT);
75 for(i=0; i<MOUNTIMG_WIDTH; i++) {
76 uint16_t *pptr = mountimg.pixels + i;
77 for(j=0; j<MOUNTIMG_HEIGHT; j++) {
82 pptr += MOUNTIMG_WIDTH;
85 destroy_image(&mountimg);
91 static void destroy(void)
97 static void start(long trans_time)
99 g3d_matrix_mode(G3D_PROJECTION);
101 g3d_perspective(VFOV, 1.3333333, 0.5, 500.0);
103 g3d_enable(G3D_CULL_FACE);
105 g3d_clear_color(85, 70, 136);
107 part_start = time_msec;
110 static void update(void)
113 float t = (time_msec - part_start) / 1000.0f;
114 struct g3d_vertex *vptr;
116 float ampl = cgm_smoothstep(TM_RIPPLE_START, TM_RIPPLE_START + TM_RIPPLE_TRANS_LEN, t);
118 mouse_orbit_update(&cam_theta, &cam_phi, &cam_dist);
122 for(i=0; i<GMESH_GRIDSZ + 1; i++) {
123 for(j=0; j<GMESH_GRIDSZ + 1; j++) {
124 float u = (float)j / GMESH_GRIDSZ - 0.5f;
125 float v = (float)i / GMESH_GRIDSZ - 0.5f;
128 float r = sqrt(x * x + y * y);
130 vptr->z = sin(x * 0.5 + t) + cos(x * 0.8f) * 0.5f;
131 vptr->z += cos(y * 0.5 + t);
132 vptr->z += sin(r + t) * 0.5f;
133 vptr->z *= r * 0.1f > 1.0f ? 1.0f : r * 0.1f;
140 static void draw(void)
146 g3d_matrix_mode(G3D_MODELVIEW);
148 g3d_translate(0, -2, -cam_dist);
149 g3d_rotate(cam_phi, 1, 0, 0);
150 g3d_rotate(cam_theta, 0, 1, 0);
152 g3d_mult_matrix(sball_matrix);
155 g3d_clear(G3D_COLOR_BUFFER_BIT | G3D_DEPTH_BUFFER_BIT);
158 g3d_set_texture(gtex.width, gtex.height, gtex.pixels);
159 g3d_enable(G3D_TEXTURE_2D);
160 g3d_enable(G3D_DEPTH_TEST);
163 g3d_rotate(-90, 1, 0, 0);
167 g3d_disable(G3D_DEPTH_TEST);
168 g3d_disable(G3D_TEXTURE_2D);
170 swap_buffers(fb_pixels);
173 /* XXX all the sptr calculations assume mountimg.width == 512 */
174 static void draw_mountains(void)
176 int i, j, horizon_y, y;
177 int32_t x, xstart, xend, dx;
178 uint16_t *dptr, *sptr;
180 /* 24.8 fixed point, 512 width, 90deg arc */
181 xstart = cround64(cam_theta * (256.0 * MOUNTIMG_WIDTH / 90.0));
182 xend = cround64((cam_theta + HFOV) * (256.0 * MOUNTIMG_WIDTH / 90.0));
183 dx = (xend - xstart) / FB_WIDTH;
186 horizon_y = cround64(-cam_phi * (FB_HEIGHT / 45.0)) + FB_HEIGHT / 2;
187 y = horizon_y - MOUNTIMG_HEIGHT;
190 /* TODO draw gradient for the sky */
194 memset(fb_pixels, 0, FB_WIDTH * FB_HEIGHT * 2);
198 for(i=0; i<FB_WIDTH; i++) {
199 int skip = mountimg_skip[(x >> 8) & 0x1ff];
200 int vspan = MOUNTIMG_HEIGHT - skip;
202 dptr = fb_pixels + (y + skip) * FB_WIDTH + i;
204 for(j=0; j<vspan; j++) {
205 *dptr = 0; /* black mountains */
212 if(horizon_y < FB_HEIGHT) {
213 memset(fb_pixels + horizon_y * FB_WIDTH, 0, (FB_HEIGHT - horizon_y) * FB_WIDTH * 2);