dostunnel

view src/tunnel.c @ 1:5d7f784002b0

foo
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 15 Mar 2013 16:49:32 +0200
parents c525cfbfd4a2
children a8024271c662
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 #include <conio.h>
6 #include "wvga.h"
7 #include "texture.h"
8 #include "palman.h"
10 #ifndef M_PI
11 #define M_PI 3.14159265
12 #endif
14 #define WIDTH 320
15 #define HEIGHT 200
17 int init(void);
18 void cleanup(void);
19 void display(void);
20 int calc_tunnel_mapping(void);
22 static unsigned char *fbuf;
23 static struct texture *tex;
24 static int colrange;
26 static char *tex_fname = "data/wall2.ppm";
28 static unsigned long *umap, *vmap;
30 static unsigned long frames;
31 static unsigned long start_time;
33 int main(int argc, char **argv)
34 {
35 if(argc > 1) {
36 tex_fname = argv[1];
37 }
39 if(init() == -1) {
40 return 1;
41 }
43 while(!kbhit()) {
44 display();
45 }
46 cleanup();
47 return 0;
48 }
50 int init(void)
51 {
52 int i;
53 struct palm_color *pal;
55 if(!(fbuf = malloc(WIDTH * HEIGHT))) {
56 fprintf(stderr, "failed to allocate framebuffer\n");
57 return -1;
58 }
60 if(calc_tunnel_mapping() == -1) {
61 fprintf(stderr, "failed to precalc tunnel mapping\n");
62 return 1;
63 }
65 if(tex_fname) {
66 if(!(tex = load_texture(tex_fname))) {
67 fprintf(stderr, "failed to load texture: %s\n", tex_fname);
68 free(fbuf);
69 return -1;
70 }
72 } else {
73 fprintf(stderr, "FOO\n");
74 return -1;
75 }
77 set_video_mode(0x13);
79 palm_build();
80 get_texture_pixels(tex);
82 pal = palm_palette();
83 for(i=0; i<palm_palette_size(); i++) {
84 set_pal_entry(i, pal[i].r, pal[i].g, pal[i].b);
85 }
86 colrange = palm_color_range();
88 return 0;
89 }
91 void cleanup(void)
92 {
93 free_texture(tex);
94 free(fbuf);
95 set_video_mode(0x3);
96 }
98 void display(void)
99 {
100 static unsigned long msec;
102 unsigned int i;
103 unsigned char voffs = msec >> 3;
104 unsigned char uoffs = msec >> 6;
106 unsigned char *fbptr = fbuf;
107 unsigned long *uptr = umap;
108 unsigned long *vptr = vmap;
110 for(i=0; i<64000; i++) {
111 unsigned long u = *uptr++;
112 unsigned long v = *vptr++;
113 unsigned long tx = ((((unsigned long)(u - uoffs) << 3) & 0xff) * tex->width) >> 8;
114 unsigned long ty = (((unsigned long)(v + voffs) & 0xff) * tex->height) >> 8;
116 unsigned long base = tex->pixels[ty * tex->width + tx];
117 long zcue_shift = colrange - (v >> 6);
118 if(zcue_shift < 0) {
119 zcue_shift = 0;
120 }
121 *fbptr++ = (unsigned char)(base + zcue_shift);
122 }
124 copy_frame(fbuf);
125 msec += 33;
126 }
128 int calc_tunnel_mapping(void)
129 {
130 int i, j;
131 unsigned long *uptr, *vptr;
132 float diag_dist = sqrt(1.33333 * 1.33333 + 1.0);
134 if(!(umap = malloc(WIDTH * HEIGHT * sizeof *umap))) {
135 return -1;
136 }
137 if(!(vmap = malloc(WIDTH * HEIGHT * sizeof *umap))) {
138 free(umap);
139 return -1;
140 }
142 uptr = umap;
143 vptr = vmap;
145 for(i=0; i<HEIGHT; i++) {
146 for(j=0; j<WIDTH; j++) {
147 float x = ((float)j / WIDTH * 2.0 - 1.0) * 1.33333;
148 float y = (float)i / HEIGHT * 2.0 - 1.0;
149 float angle, z, dist;
151 if(fabs(x) > 0.00001) {
152 angle = atan2(y, x) + M_PI;
153 } else {
154 angle = y < 0.0 ? M_PI / 2.0 : 3.0 * M_PI / 2.0;
155 }
156 dist = sqrt(x * x + y * y);
157 z = 2.0 / dist;
159 *uptr++ = (unsigned int)(angle * 0.5 / M_PI * 255.0);
160 *vptr++ = (unsigned int)(z * 255.0);
161 }
162 }
163 return 0;
164 }