dostunnel
diff src/tunnel.c @ 0:c525cfbfd4a2
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 15 Mar 2013 16:46:41 +0200 |
parents | |
children | 5d7f784002b0 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/tunnel.c Fri Mar 15 16:46:41 2013 +0200 1.3 @@ -0,0 +1,164 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <math.h> 1.8 +#include <conio.h> 1.9 +#include "wvga.h" 1.10 +#include "texture.h" 1.11 +#include "palman.h" 1.12 + 1.13 +#ifndef M_PI 1.14 +#define M_PI 3.14159265 1.15 +#endif 1.16 + 1.17 +#define WIDTH 320 1.18 +#define HEIGHT 200 1.19 + 1.20 +int init(void); 1.21 +void cleanup(void); 1.22 +void display(void); 1.23 +int calc_tunnel_mapping(void); 1.24 + 1.25 +static unsigned char *fbuf; 1.26 +static struct texture *tex; 1.27 +static int colrange; 1.28 + 1.29 +static char *tex_fname; 1.30 + 1.31 +static unsigned long *umap, *vmap; 1.32 + 1.33 +static unsigned long frames; 1.34 +static unsigned long start_time; 1.35 + 1.36 +int main(int argc, char **argv) 1.37 +{ 1.38 + if(argc > 1) { 1.39 + tex_fname = argv[1]; 1.40 + } 1.41 + 1.42 + if(init() == -1) { 1.43 + return 1; 1.44 + } 1.45 + 1.46 + while(!kbhit()) { 1.47 + display(); 1.48 + } 1.49 + cleanup(); 1.50 + return 0; 1.51 +} 1.52 + 1.53 +int init(void) 1.54 +{ 1.55 + int i; 1.56 + struct palm_color *pal; 1.57 + 1.58 + if(!(fbuf = malloc(WIDTH * HEIGHT))) { 1.59 + fprintf(stderr, "failed to allocate framebuffer\n"); 1.60 + return -1; 1.61 + } 1.62 + 1.63 + if(calc_tunnel_mapping() == -1) { 1.64 + fprintf(stderr, "failed to precalc tunnel mapping\n"); 1.65 + return 1; 1.66 + } 1.67 + 1.68 + if(tex_fname) { 1.69 + if(!(tex = load_texture(tex_fname))) { 1.70 + fprintf(stderr, "failed to load texture: %s\n", tex_fname); 1.71 + free(fbuf); 1.72 + return -1; 1.73 + } 1.74 + 1.75 + } else { 1.76 + fprintf(stderr, "FOO\n"); 1.77 + return -1; 1.78 + } 1.79 + 1.80 + set_video_mode(0x13); 1.81 + 1.82 + palm_build(); 1.83 + get_texture_pixels(tex); 1.84 + 1.85 + pal = palm_palette(); 1.86 + for(i=0; i<palm_palette_size(); i++) { 1.87 + set_pal_entry(i, pal[i].r, pal[i].g, pal[i].b); 1.88 + } 1.89 + colrange = palm_color_range(); 1.90 + 1.91 + return 0; 1.92 +} 1.93 + 1.94 +void cleanup(void) 1.95 +{ 1.96 + free_texture(tex); 1.97 + free(fbuf); 1.98 + set_video_mode(0x3); 1.99 +} 1.100 + 1.101 +void display(void) 1.102 +{ 1.103 + static unsigned long msec; 1.104 + 1.105 + unsigned int i; 1.106 + unsigned char voffs = msec >> 3; 1.107 + unsigned char uoffs = msec >> 6; 1.108 + 1.109 + unsigned char *fbptr = fbuf; 1.110 + unsigned long *uptr = umap; 1.111 + unsigned long *vptr = vmap; 1.112 + 1.113 + for(i=0; i<64000; i++) { 1.114 + unsigned long u = *uptr++; 1.115 + unsigned long v = *vptr++; 1.116 + unsigned long tx = ((((unsigned long)(u - uoffs) << 3) & 0xff) * tex->width) >> 8; 1.117 + unsigned long ty = (((unsigned long)(v + voffs) & 0xff) * tex->height) >> 8; 1.118 + 1.119 + unsigned long base = tex->pixels[ty * tex->width + tx]; 1.120 + long zcue_shift = colrange - (v >> 6); 1.121 + if(zcue_shift < 0) { 1.122 + zcue_shift = 0; 1.123 + } 1.124 + *fbptr++ = (unsigned char)(base + zcue_shift); 1.125 + } 1.126 + 1.127 + copy_frame(fbuf); 1.128 + msec += 33; 1.129 +} 1.130 + 1.131 +int calc_tunnel_mapping(void) 1.132 +{ 1.133 + int i, j; 1.134 + unsigned long *uptr, *vptr; 1.135 + float diag_dist = sqrt(1.33333 * 1.33333 + 1.0); 1.136 + 1.137 + if(!(umap = malloc(WIDTH * HEIGHT * sizeof *umap))) { 1.138 + return -1; 1.139 + } 1.140 + if(!(vmap = malloc(WIDTH * HEIGHT * sizeof *umap))) { 1.141 + free(umap); 1.142 + return -1; 1.143 + } 1.144 + 1.145 + uptr = umap; 1.146 + vptr = vmap; 1.147 + 1.148 + for(i=0; i<HEIGHT; i++) { 1.149 + for(j=0; j<WIDTH; j++) { 1.150 + float x = ((float)j / WIDTH * 2.0 - 1.0) * 1.33333; 1.151 + float y = (float)i / HEIGHT * 2.0 - 1.0; 1.152 + float angle, z, dist; 1.153 + 1.154 + if(fabs(x) > 0.00001) { 1.155 + angle = atan2(y, x) + M_PI; 1.156 + } else { 1.157 + angle = y < 0.0 ? M_PI / 2.0 : 3.0 * M_PI / 2.0; 1.158 + } 1.159 + dist = sqrt(x * x + y * y); 1.160 + z = 2.0 / dist; 1.161 + 1.162 + *uptr++ = (unsigned int)(angle * 0.5 / M_PI * 255.0); 1.163 + *vptr++ = (unsigned int)(z * 255.0); 1.164 + } 1.165 + } 1.166 + return 0; 1.167 +}