rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@0
|
3 #include <string.h>
|
nuclear@0
|
4 #include <math.h>
|
nuclear@0
|
5 #include <conio.h>
|
nuclear@0
|
6 #include "wvga.h"
|
nuclear@0
|
7 #include "texture.h"
|
nuclear@0
|
8 #include "palman.h"
|
nuclear@3
|
9 #include "timer.h"
|
nuclear@0
|
10
|
nuclear@0
|
11 #ifndef M_PI
|
nuclear@0
|
12 #define M_PI 3.14159265
|
nuclear@0
|
13 #endif
|
nuclear@0
|
14
|
nuclear@0
|
15 #define WIDTH 320
|
nuclear@0
|
16 #define HEIGHT 200
|
nuclear@0
|
17
|
nuclear@0
|
18 int init(void);
|
nuclear@0
|
19 void cleanup(void);
|
nuclear@0
|
20 void display(void);
|
nuclear@0
|
21 int calc_tunnel_mapping(void);
|
nuclear@3
|
22 int parse_args(int argc, char **argv);
|
nuclear@0
|
23
|
nuclear@0
|
24 static unsigned char *fbuf;
|
nuclear@0
|
25 static struct texture *tex;
|
nuclear@0
|
26 static int colrange;
|
nuclear@0
|
27
|
nuclear@3
|
28 static char *tex_fname;
|
nuclear@0
|
29
|
nuclear@0
|
30 static unsigned long *umap, *vmap;
|
nuclear@0
|
31
|
nuclear@0
|
32 static unsigned long frames;
|
nuclear@0
|
33 static unsigned long start_time;
|
nuclear@0
|
34
|
nuclear@3
|
35 static int under_windows;
|
nuclear@3
|
36
|
nuclear@3
|
37
|
nuclear@0
|
38 int main(int argc, char **argv)
|
nuclear@0
|
39 {
|
nuclear@3
|
40 if(parse_args(argc, argv) == -1) {
|
nuclear@3
|
41 return 1;
|
nuclear@0
|
42 }
|
nuclear@0
|
43
|
nuclear@0
|
44 if(init() == -1) {
|
nuclear@0
|
45 return 1;
|
nuclear@0
|
46 }
|
nuclear@0
|
47
|
nuclear@0
|
48 while(!kbhit()) {
|
nuclear@0
|
49 display();
|
nuclear@0
|
50 }
|
nuclear@0
|
51 cleanup();
|
nuclear@0
|
52 return 0;
|
nuclear@0
|
53 }
|
nuclear@0
|
54
|
nuclear@0
|
55 int init(void)
|
nuclear@0
|
56 {
|
nuclear@0
|
57 int i;
|
nuclear@0
|
58 struct palm_color *pal;
|
nuclear@0
|
59
|
nuclear@0
|
60 if(!(fbuf = malloc(WIDTH * HEIGHT))) {
|
nuclear@0
|
61 fprintf(stderr, "failed to allocate framebuffer\n");
|
nuclear@0
|
62 return -1;
|
nuclear@0
|
63 }
|
nuclear@0
|
64
|
nuclear@0
|
65 if(calc_tunnel_mapping() == -1) {
|
nuclear@0
|
66 fprintf(stderr, "failed to precalc tunnel mapping\n");
|
nuclear@0
|
67 return 1;
|
nuclear@0
|
68 }
|
nuclear@0
|
69
|
nuclear@0
|
70 if(tex_fname) {
|
nuclear@0
|
71 if(!(tex = load_texture(tex_fname))) {
|
nuclear@0
|
72 fprintf(stderr, "failed to load texture: %s\n", tex_fname);
|
nuclear@0
|
73 free(fbuf);
|
nuclear@0
|
74 return -1;
|
nuclear@0
|
75 }
|
nuclear@0
|
76 } else {
|
nuclear@3
|
77 fprintf(stderr, "you must specify a texture to use\n");
|
nuclear@0
|
78 return -1;
|
nuclear@0
|
79 }
|
nuclear@0
|
80
|
nuclear@0
|
81 set_video_mode(0x13);
|
nuclear@0
|
82
|
nuclear@0
|
83 palm_build();
|
nuclear@0
|
84 get_texture_pixels(tex);
|
nuclear@0
|
85
|
nuclear@0
|
86 pal = palm_palette();
|
nuclear@0
|
87 for(i=0; i<palm_palette_size(); i++) {
|
nuclear@0
|
88 set_pal_entry(i, pal[i].r, pal[i].g, pal[i].b);
|
nuclear@0
|
89 }
|
nuclear@0
|
90 colrange = palm_color_range();
|
nuclear@0
|
91
|
nuclear@3
|
92 init_timer(120);
|
nuclear@3
|
93 start_time = get_msec();
|
nuclear@3
|
94
|
nuclear@0
|
95 return 0;
|
nuclear@0
|
96 }
|
nuclear@0
|
97
|
nuclear@0
|
98 void cleanup(void)
|
nuclear@0
|
99 {
|
nuclear@3
|
100 unsigned long sec = (get_msec() - start_time) / 1000ul;
|
nuclear@3
|
101
|
nuclear@0
|
102 free_texture(tex);
|
nuclear@0
|
103 free(fbuf);
|
nuclear@0
|
104 set_video_mode(0x3);
|
nuclear@3
|
105
|
nuclear@3
|
106 if(sec) {
|
nuclear@3
|
107 printf("avg fps: %lu\n", frames / sec);
|
nuclear@3
|
108 }
|
nuclear@0
|
109 }
|
nuclear@0
|
110
|
nuclear@0
|
111 void display(void)
|
nuclear@0
|
112 {
|
nuclear@3
|
113 unsigned long msec = get_msec() - start_time;
|
nuclear@0
|
114
|
nuclear@0
|
115 unsigned int i;
|
nuclear@0
|
116 unsigned char voffs = msec >> 3;
|
nuclear@0
|
117 unsigned char uoffs = msec >> 6;
|
nuclear@0
|
118
|
nuclear@0
|
119 unsigned char *fbptr = fbuf;
|
nuclear@0
|
120 unsigned long *uptr = umap;
|
nuclear@0
|
121 unsigned long *vptr = vmap;
|
nuclear@0
|
122
|
nuclear@0
|
123 for(i=0; i<64000; i++) {
|
nuclear@0
|
124 unsigned long u = *uptr++;
|
nuclear@0
|
125 unsigned long v = *vptr++;
|
nuclear@0
|
126 unsigned long tx = ((((unsigned long)(u - uoffs) << 3) & 0xff) * tex->width) >> 8;
|
nuclear@0
|
127 unsigned long ty = (((unsigned long)(v + voffs) & 0xff) * tex->height) >> 8;
|
nuclear@0
|
128
|
nuclear@0
|
129 unsigned long base = tex->pixels[ty * tex->width + tx];
|
nuclear@0
|
130 long zcue_shift = colrange - (v >> 6);
|
nuclear@0
|
131 if(zcue_shift < 0) {
|
nuclear@0
|
132 zcue_shift = 0;
|
nuclear@0
|
133 }
|
nuclear@0
|
134 *fbptr++ = (unsigned char)(base + zcue_shift);
|
nuclear@0
|
135 }
|
nuclear@0
|
136
|
nuclear@0
|
137 copy_frame(fbuf);
|
nuclear@3
|
138 frames++;
|
nuclear@0
|
139 }
|
nuclear@0
|
140
|
nuclear@0
|
141 int calc_tunnel_mapping(void)
|
nuclear@0
|
142 {
|
nuclear@0
|
143 int i, j;
|
nuclear@0
|
144 unsigned long *uptr, *vptr;
|
nuclear@0
|
145 float diag_dist = sqrt(1.33333 * 1.33333 + 1.0);
|
nuclear@0
|
146
|
nuclear@0
|
147 if(!(umap = malloc(WIDTH * HEIGHT * sizeof *umap))) {
|
nuclear@0
|
148 return -1;
|
nuclear@0
|
149 }
|
nuclear@0
|
150 if(!(vmap = malloc(WIDTH * HEIGHT * sizeof *umap))) {
|
nuclear@0
|
151 free(umap);
|
nuclear@0
|
152 return -1;
|
nuclear@0
|
153 }
|
nuclear@0
|
154
|
nuclear@0
|
155 uptr = umap;
|
nuclear@0
|
156 vptr = vmap;
|
nuclear@0
|
157
|
nuclear@0
|
158 for(i=0; i<HEIGHT; i++) {
|
nuclear@0
|
159 for(j=0; j<WIDTH; j++) {
|
nuclear@0
|
160 float x = ((float)j / WIDTH * 2.0 - 1.0) * 1.33333;
|
nuclear@0
|
161 float y = (float)i / HEIGHT * 2.0 - 1.0;
|
nuclear@0
|
162 float angle, z, dist;
|
nuclear@0
|
163
|
nuclear@0
|
164 if(fabs(x) > 0.00001) {
|
nuclear@0
|
165 angle = atan2(y, x) + M_PI;
|
nuclear@0
|
166 } else {
|
nuclear@0
|
167 angle = y < 0.0 ? M_PI / 2.0 : 3.0 * M_PI / 2.0;
|
nuclear@0
|
168 }
|
nuclear@0
|
169 dist = sqrt(x * x + y * y);
|
nuclear@0
|
170 z = 2.0 / dist;
|
nuclear@0
|
171
|
nuclear@0
|
172 *uptr++ = (unsigned int)(angle * 0.5 / M_PI * 255.0);
|
nuclear@0
|
173 *vptr++ = (unsigned int)(z * 255.0);
|
nuclear@0
|
174 }
|
nuclear@0
|
175 }
|
nuclear@0
|
176 return 0;
|
nuclear@0
|
177 }
|
nuclear@3
|
178
|
nuclear@3
|
179 int parse_args(int argc, char **argv)
|
nuclear@3
|
180 {
|
nuclear@3
|
181 int i;
|
nuclear@3
|
182
|
nuclear@3
|
183 for(i=1; i<argc; i++) {
|
nuclear@3
|
184 if(argv[i][0] == '-') {
|
nuclear@3
|
185 if(strcmp(argv[i], "-win") == 0) {
|
nuclear@3
|
186 under_windows = 1;
|
nuclear@3
|
187 } else {
|
nuclear@3
|
188 fprintf(stderr, "invalid option: %s\n", argv[i]);
|
nuclear@3
|
189 return -1;
|
nuclear@3
|
190 }
|
nuclear@3
|
191 } else {
|
nuclear@3
|
192 if(tex_fname) {
|
nuclear@3
|
193 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
|
nuclear@3
|
194 return -1;
|
nuclear@3
|
195 }
|
nuclear@3
|
196 tex_fname = argv[i];
|
nuclear@3
|
197 }
|
nuclear@3
|
198 }
|
nuclear@3
|
199
|
nuclear@3
|
200 if(!tex_fname) {
|
nuclear@3
|
201 tex_fname = "data/wall2.ppm";
|
nuclear@3
|
202 }
|
nuclear@3
|
203 return 0;
|
nuclear@3
|
204 }
|