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 +}