dostunnel

annotate src/tunnel.c @ 3:a8024271c662

added timer
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 16 Mar 2013 03:35:08 +0200
parents 5d7f784002b0
children ba868d348de8
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 }