dostunnel

changeset 0:c525cfbfd4a2

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 15 Mar 2013 16:46:41 +0200
parents
children 5d7f784002b0
files .hgignore Makefile dos4gw.exe src/colorbit.h src/dpmi.c src/dpmi.h src/inttypes.h src/palman.c src/palman.h src/texture.c src/texture.h src/tunnel.c src/wvga.c src/wvga.h
diffstat 14 files changed, 723 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Fri Mar 15 16:46:41 2013 +0200
     1.3 @@ -0,0 +1,2 @@
     1.4 +\.obj$
     1.5 +^wtunnel.exe$
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/Makefile	Fri Mar 15 16:46:41 2013 +0200
     2.3 @@ -0,0 +1,22 @@
     2.4 +obj = tunnel.obj &
     2.5 +      wvga.obj &
     2.6 +      dpmi.obj &
     2.7 +      palman.obj &
     2.8 +      texture.obj
     2.9 +bin = wtunnel.exe
    2.10 +
    2.11 +CC = wcc386
    2.12 +CFLAGS = -fp5 -ot
    2.13 +LD = wlink
    2.14 +
    2.15 +$(bin): $(obj)
    2.16 +	$(LD) name $@ file { $(obj) } $(LDFLAGS)
    2.17 +
    2.18 +.c: src\
    2.19 +
    2.20 +.c.obj: .autodepend
    2.21 +	$(CC) $(CFLAGS) $[*
    2.22 +
    2.23 +clean: .symbolic
    2.24 +	del *.obj
    2.25 +	del $(bin)
     3.1 Binary file dos4gw.exe has changed
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/colorbit.h	Fri Mar 15 16:46:41 2013 +0200
     4.3 @@ -0,0 +1,17 @@
     4.4 +#ifndef COLORBIT_H_
     4.5 +#define COLORBIT_H_
     4.6 +
     4.7 +#define RSHIFT	0
     4.8 +#define GSHIFT	8
     4.9 +#define BSHIFT	16
    4.10 +
    4.11 +#define PACK_COLOR24(r, g, b) \
    4.12 +	((((r) & 0xff) << RSHIFT) | \
    4.13 +	 (((g) & 0xff) << GSHIFT) | \
    4.14 +	 (((b) & 0xff) << BSHIFT))
    4.15 +
    4.16 +#define UNP_RED32(x) (((x) >> RSHIFT) & 0xff)
    4.17 +#define UNP_GREEN32(x) (((x) >> GSHIFT) & 0xff)
    4.18 +#define UNP_BLUE32(x) (((x) >> BSHIFT) & 0xff)
    4.19 +
    4.20 +#endif	/* COLORBIT_H_ */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/dpmi.c	Fri Mar 15 16:46:41 2013 +0200
     5.3 @@ -0,0 +1,55 @@
     5.4 +#include "dpmi.h"
     5.5 +
     5.6 +void dpmi_real_int(int inum, struct dpmi_real_regs *regs)
     5.7 +{
     5.8 +	unsigned char int_num = (unsigned char)inum;
     5.9 +	__asm {
    5.10 +		mov eax, 0x300
    5.11 +		mov edi, regs
    5.12 +		mov bl, int_num
    5.13 +		mov bh, 0
    5.14 +		xor ecx, ecx
    5.15 +		int 0x31
    5.16 +	}
    5.17 +}
    5.18 +
    5.19 +void *dpmi_mmap(uint32_t phys_addr, unsigned int size)
    5.20 +{
    5.21 +	uint16_t mem_high, mem_low;
    5.22 +	uint16_t phys_high = phys_addr >> 16;
    5.23 +	uint16_t phys_low = phys_addr & 0xffff;
    5.24 +	uint16_t size_high = size >> 16;
    5.25 +	uint16_t size_low = size & 0xffff;
    5.26 +	unsigned int err, res = 0;
    5.27 +
    5.28 +	__asm {
    5.29 +		mov eax, 0x800
    5.30 +		mov bx, phys_high
    5.31 +		mov cx, phys_low
    5.32 +		mov si, size_high
    5.33 +		mov di, size_low
    5.34 +		int 0x31
    5.35 +		add res, 1
    5.36 +		mov err, eax
    5.37 +		mov mem_high, bx
    5.38 +		mov mem_low, cx
    5.39 +	}
    5.40 +
    5.41 +	if(res == 2) {
    5.42 +		return 0;
    5.43 +	}
    5.44 +	return (void*)(((uint32_t)mem_high << 16) | ((uint32_t)mem_low));
    5.45 +}
    5.46 +
    5.47 +void dpmi_munmap(void *addr)
    5.48 +{
    5.49 +	uint16_t mem_high = (uint32_t)addr >> 16;
    5.50 +	uint16_t mem_low = (uint16_t)addr;
    5.51 +
    5.52 +	__asm {
    5.53 +		mov eax, 0x801
    5.54 +		mov bx, mem_high
    5.55 +		mov cx, mem_low
    5.56 +		int 0x31
    5.57 +	}
    5.58 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/dpmi.h	Fri Mar 15 16:46:41 2013 +0200
     6.3 @@ -0,0 +1,26 @@
     6.4 +#ifndef DPMI_H_
     6.5 +#define DPMI_H_
     6.6 +
     6.7 +#include "inttypes.h"
     6.8 +
     6.9 +struct dpmi_real_regs {
    6.10 +	uint32_t edi, esi, ebp;
    6.11 +	uint32_t reserved;
    6.12 +	uint32_t ebx, edx, ecx, eax;
    6.13 +	uint16_t flags;
    6.14 +	uint16_t es, ds, fs, gs;
    6.15 +	uint16_t ip, cs, sp, ss;
    6.16 +};
    6.17 +
    6.18 +unsigned short dpmi_alloc(unsigned int par);
    6.19 +#pragma aux dpmi_alloc = \
    6.20 +		"mov eax, 0x100" \
    6.21 +		"int 0x31" \
    6.22 +		value[ax] parm[ebx];
    6.23 +
    6.24 +void dpmi_real_int(int inum, struct dpmi_real_regs *regs);
    6.25 +
    6.26 +void *dpmi_mmap(uint32_t phys_addr, unsigned int size);
    6.27 +void dpmi_munmap(void *addr);
    6.28 +
    6.29 +#endif	/* DPMI_H_ */
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/inttypes.h	Fri Mar 15 16:46:41 2013 +0200
     7.3 @@ -0,0 +1,12 @@
     7.4 +#ifndef INT_TYPES_H_
     7.5 +#define INT_TYPES_H_
     7.6 +
     7.7 +typedef char int8_t;
     7.8 +typedef short int16_t;
     7.9 +typedef long int32_t;
    7.10 +
    7.11 +typedef unsigned char uint8_t;
    7.12 +typedef unsigned short uint16_t;
    7.13 +typedef unsigned long uint32_t;
    7.14 +
    7.15 +#endif	/* INT_TYPES_H_ */
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/palman.c	Fri Mar 15 16:46:41 2013 +0200
     8.3 @@ -0,0 +1,124 @@
     8.4 +/*
     8.5 +256-color 3D graphics hack for real-mode DOS.
     8.6 +Copyright (C) 2011  John Tsiombikas <nuclear@member.fsf.org>
     8.7 +
     8.8 +This program is free software: you can redistribute it and/or modify
     8.9 +it under the terms of the GNU General Public License as published by
    8.10 +the Free Software Foundation, either version 3 of the License, or
    8.11 +(at your option) any later version.
    8.12 +
    8.13 +This program is distributed in the hope that it will be useful,
    8.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.16 +GNU General Public License for more details.
    8.17 +
    8.18 +You should have received a copy of the GNU General Public License
    8.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
    8.20 +*/
    8.21 +
    8.22 +#include <string.h>
    8.23 +#include "palman.h"
    8.24 +
    8.25 +#define MAX_COLORS		256
    8.26 +static struct palm_color colors[MAX_COLORS];
    8.27 +static int base_index[MAX_COLORS];
    8.28 +
    8.29 +static struct palm_color pal[MAX_COLORS];
    8.30 +static unsigned int ncol, pcol;
    8.31 +static int range;
    8.32 +
    8.33 +void palm_clear(void)
    8.34 +{
    8.35 +	ncol = 0;
    8.36 +}
    8.37 +
    8.38 +int palm_add_color(unsigned char r, unsigned char g, unsigned char b)
    8.39 +{
    8.40 +	if(ncol >= MAX_COLORS) {
    8.41 +		return -1;
    8.42 +	}
    8.43 +	colors[ncol].r = r;
    8.44 +	colors[ncol].g = g;
    8.45 +	colors[ncol].b = b;
    8.46 +	ncol++;
    8.47 +	return 0;
    8.48 +}
    8.49 +
    8.50 +int palm_color_index(unsigned char r, unsigned char g, unsigned char b)
    8.51 +{
    8.52 +	int i;
    8.53 +
    8.54 +	for(i=0; i<ncol; i++) {
    8.55 +		if(colors[i].r == r && colors[i].g == g && colors[i].b == b) {
    8.56 +			return i;
    8.57 +		}
    8.58 +	}
    8.59 +	return -1;
    8.60 +}
    8.61 +
    8.62 +/* TODO: build an octree */
    8.63 +int palm_build(void)
    8.64 +{
    8.65 +	int i, j;
    8.66 +
    8.67 +	if(!ncol) {
    8.68 +		return -1;
    8.69 +	}
    8.70 +
    8.71 +	/* gradient range for each color */
    8.72 +	range = MAX_COLORS / ncol;
    8.73 +
    8.74 +	if(range <= 1) {
    8.75 +		memcpy(pal, colors, ncol * sizeof *pal);
    8.76 +		return 0;
    8.77 +	}
    8.78 +	pcol = 0;
    8.79 +
    8.80 +	for(i=0; i<ncol; i++) {
    8.81 +		unsigned short r, g, b, dr, dg, db;
    8.82 +
    8.83 +		base_index[i] = pcol;
    8.84 +
    8.85 +		dr = ((unsigned short)colors[i].r << 8) / (range - 1);
    8.86 +		dg = ((unsigned short)colors[i].g << 8) / (range - 1);
    8.87 +		db = ((unsigned short)colors[i].b << 8) / (range - 1);
    8.88 +
    8.89 +		r = g = b = 0;
    8.90 +		for(j=0; j<range; j++) {
    8.91 +			pal[pcol].r = (unsigned char)(r >> 8);
    8.92 +			pal[pcol].g = (unsigned char)(g >> 8);
    8.93 +			pal[pcol].b = (unsigned char)(b >> 8);
    8.94 +			pcol++;
    8.95 +			r += dr;
    8.96 +			g += dg;
    8.97 +			b += db;
    8.98 +		}
    8.99 +	}
   8.100 +	return pcol;
   8.101 +}
   8.102 +
   8.103 +struct palm_color *palm_palette(void)
   8.104 +{
   8.105 +	return pal;
   8.106 +}
   8.107 +
   8.108 +int palm_palette_size(void)
   8.109 +{
   8.110 +	return pcol;
   8.111 +}
   8.112 +
   8.113 +
   8.114 +int palm_color_base(unsigned char r, unsigned char g, unsigned char b)
   8.115 +{
   8.116 +	int c;
   8.117 +
   8.118 +	if((c = palm_color_index(r, g, b)) == -1) {
   8.119 +		return -1;
   8.120 +	}
   8.121 +	return base_index[c];
   8.122 +}
   8.123 +
   8.124 +int palm_color_range(void)
   8.125 +{
   8.126 +	return range;
   8.127 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/palman.h	Fri Mar 15 16:46:41 2013 +0200
     9.3 @@ -0,0 +1,39 @@
     9.4 +/*
     9.5 +256-color 3D graphics hack for real-mode DOS.
     9.6 +Copyright (C) 2011  John Tsiombikas <nuclear@member.fsf.org>
     9.7 +
     9.8 +This program is free software: you can redistribute it and/or modify
     9.9 +it under the terms of the GNU General Public License as published by
    9.10 +the Free Software Foundation, either version 3 of the License, or
    9.11 +(at your option) any later version.
    9.12 +
    9.13 +This program is distributed in the hope that it will be useful,
    9.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9.16 +GNU General Public License for more details.
    9.17 +
    9.18 +You should have received a copy of the GNU General Public License
    9.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
    9.20 +*/
    9.21 +
    9.22 +#ifndef PALMAN_H_
    9.23 +#define PALMAN_H_
    9.24 +
    9.25 +struct palm_color {
    9.26 +	unsigned char r, g, b;
    9.27 +};
    9.28 +
    9.29 +void palm_clear(void);
    9.30 +int palm_add_color(unsigned char r, unsigned char g, unsigned char b);
    9.31 +int palm_color_index(unsigned char r, unsigned char g, unsigned char b);
    9.32 +
    9.33 +int palm_build(void);
    9.34 +
    9.35 +struct palm_color *palm_palette(void);
    9.36 +int palm_palette_size(void);
    9.37 +
    9.38 +int palm_color_base(unsigned char r, unsigned char g, unsigned char b);
    9.39 +int palm_color_range(void);
    9.40 +
    9.41 +
    9.42 +#endif	/* PALMAN_H_ */
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/texture.c	Fri Mar 15 16:46:41 2013 +0200
    10.3 @@ -0,0 +1,136 @@
    10.4 +/*
    10.5 +256-color 3D graphics hack for real-mode DOS.
    10.6 +Copyright (C) 2011  John Tsiombikas <nuclear@member.fsf.org>
    10.7 +
    10.8 +This program is free software: you can redistribute it and/or modify
    10.9 +it under the terms of the GNU General Public License as published by
   10.10 +the Free Software Foundation, either version 3 of the License, or
   10.11 +(at your option) any later version.
   10.12 +
   10.13 +This program is distributed in the hope that it will be useful,
   10.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.16 +GNU General Public License for more details.
   10.17 +
   10.18 +You should have received a copy of the GNU General Public License
   10.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   10.20 +*/
   10.21 +
   10.22 +#include <stdio.h>
   10.23 +#include <string.h>
   10.24 +#include <stdlib.h>
   10.25 +#include "texture.h"
   10.26 +#include "palman.h"
   10.27 +
   10.28 +struct texture *load_texture(const char *fname)
   10.29 +{
   10.30 +	long i, num_pixels;
   10.31 +	struct texture *tex;
   10.32 +	long fpos;
   10.33 +
   10.34 +	if(!(tex = malloc(sizeof *tex))) {
   10.35 +		return 0;
   10.36 +	}
   10.37 +	memset(tex, 0, sizeof *tex);
   10.38 +
   10.39 +	if(!(tex->file = fopen(fname, "rb"))) {
   10.40 +		fprintf(stderr, "failed to open texture: %s\n", fname);
   10.41 +		free_texture(tex);
   10.42 +		return 0;
   10.43 +	}
   10.44 +	if(fscanf(tex->file, "P6 %d %d 255 ", &tex->width, &tex->height) != 2) {
   10.45 +		fprintf(stderr, "invalid pixmap: %s\n", fname);
   10.46 +		free_texture(tex);
   10.47 +		return 0;
   10.48 +	}
   10.49 +	fpos = ftell(tex->file);
   10.50 +
   10.51 +	num_pixels = tex->width * tex->height;
   10.52 +	for(i=0; i<num_pixels; i++) {
   10.53 +		int r, g, b;
   10.54 +
   10.55 +		r = fgetc(tex->file);
   10.56 +		g = fgetc(tex->file);
   10.57 +		b = fgetc(tex->file);
   10.58 +
   10.59 +		if(feof(tex->file)) {
   10.60 +			fprintf(stderr, "unexpected EOF while reading: %s\n", fname);
   10.61 +			free_texture(tex);
   10.62 +			return 0;
   10.63 +		}
   10.64 +
   10.65 +		if(palm_color_index(r, g, b) == -1) {
   10.66 +			palm_add_color(r, g, b);
   10.67 +		}
   10.68 +	}
   10.69 +	fseek(tex->file, fpos, SEEK_SET);
   10.70 +	return tex;
   10.71 +}
   10.72 +
   10.73 +void free_texture(struct texture *tex)
   10.74 +{
   10.75 +	if(tex) {
   10.76 +		if(tex->file) {
   10.77 +			fclose(tex->file);
   10.78 +		}
   10.79 +		free(tex->pixels);
   10.80 +		free(tex);
   10.81 +	}
   10.82 +}
   10.83 +
   10.84 +unsigned char *get_texture_pixels(struct texture *tex)
   10.85 +{
   10.86 +	if(!tex->pixels && tex->file) {
   10.87 +		long i, num_pixels = tex->width * tex->height;
   10.88 +
   10.89 +		if(!(tex->pixels = malloc(num_pixels))) {
   10.90 +			return 0;
   10.91 +		}
   10.92 +
   10.93 +		for(i=0; i<num_pixels; i++) {
   10.94 +			int r, g, b, base;
   10.95 +
   10.96 +			r = fgetc(tex->file);
   10.97 +			g = fgetc(tex->file);
   10.98 +			b = fgetc(tex->file);
   10.99 +
  10.100 +			if((base = palm_color_base(r, g, b)) == -1) {
  10.101 +				base = 0;
  10.102 +			}
  10.103 +			tex->pixels[i] = base;
  10.104 +		}
  10.105 +
  10.106 +		fclose(tex->file);
  10.107 +		tex->file = 0;
  10.108 +	}
  10.109 +
  10.110 +	return tex->pixels;
  10.111 +}
  10.112 +
  10.113 +struct texture *tex_gen_checker(int xsz, int ysz, int ush, int vsh, int c1, int c2)
  10.114 +{
  10.115 +	int i, j;
  10.116 +	struct texture *tex;
  10.117 +	unsigned char *pptr;
  10.118 +
  10.119 +	if(!(tex = malloc(sizeof *tex))) {
  10.120 +		return 0;
  10.121 +	}
  10.122 +	memset(tex, 0, sizeof *tex);
  10.123 +
  10.124 +	if(!(tex->pixels = malloc(xsz * ysz))) {
  10.125 +		free(tex);
  10.126 +		return 0;
  10.127 +	}
  10.128 +	tex->width = xsz;
  10.129 +	tex->height = ysz;
  10.130 +
  10.131 +	pptr = tex->pixels;
  10.132 +	for(i=0; i<ysz; i++) {
  10.133 +		for(j=0; j<xsz; j++) {
  10.134 +			int c = ((i >> vsh) & 1) == ((j >> ush) & 1) ? c1 : c2;
  10.135 +			*pptr++ = c;
  10.136 +		}
  10.137 +	}
  10.138 +	return tex;
  10.139 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/texture.h	Fri Mar 15 16:46:41 2013 +0200
    11.3 @@ -0,0 +1,41 @@
    11.4 +/*
    11.5 +256-color 3D graphics hack for real-mode DOS.
    11.6 +Copyright (C) 2011  John Tsiombikas <nuclear@member.fsf.org>
    11.7 +
    11.8 +This program is free software: you can redistribute it and/or modify
    11.9 +it under the terms of the GNU General Public License as published by
   11.10 +the Free Software Foundation, either version 3 of the License, or
   11.11 +(at your option) any later version.
   11.12 +
   11.13 +This program is distributed in the hope that it will be useful,
   11.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.16 +GNU General Public License for more details.
   11.17 +
   11.18 +You should have received a copy of the GNU General Public License
   11.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   11.20 +*/
   11.21 +#ifndef TEXTURE_H_
   11.22 +#define TEXTURE_H_
   11.23 +
   11.24 +struct texture {
   11.25 +	int width, height;
   11.26 +	unsigned char *pixels;
   11.27 +
   11.28 +	struct {
   11.29 +		unsigned char r, g, b;
   11.30 +	} *palette;
   11.31 +	int num_colors;
   11.32 +
   11.33 +	FILE *file;
   11.34 +};
   11.35 +
   11.36 +struct texture *load_texture(const char *fname);
   11.37 +void free_texture(struct texture *tex);
   11.38 +
   11.39 +unsigned char *get_texture_pixels(struct texture *tex);
   11.40 +int find_texture_color(struct texture *tex, int r, int g, int b);
   11.41 +
   11.42 +struct texture *tex_gen_checker(int xsz, int ysz, int usub, int vsub, int c1, int c2);
   11.43 +
   11.44 +#endif	/* TEXTURE_H_ */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/tunnel.c	Fri Mar 15 16:46:41 2013 +0200
    12.3 @@ -0,0 +1,164 @@
    12.4 +#include <stdio.h>
    12.5 +#include <stdlib.h>
    12.6 +#include <string.h>
    12.7 +#include <math.h>
    12.8 +#include <conio.h>
    12.9 +#include "wvga.h"
   12.10 +#include "texture.h"
   12.11 +#include "palman.h"
   12.12 +
   12.13 +#ifndef M_PI
   12.14 +#define M_PI	3.14159265
   12.15 +#endif
   12.16 +
   12.17 +#define WIDTH	320
   12.18 +#define HEIGHT	200
   12.19 +
   12.20 +int init(void);
   12.21 +void cleanup(void);
   12.22 +void display(void);
   12.23 +int calc_tunnel_mapping(void);
   12.24 +
   12.25 +static unsigned char *fbuf;
   12.26 +static struct texture *tex;
   12.27 +static int colrange;
   12.28 +
   12.29 +static char *tex_fname;
   12.30 +
   12.31 +static unsigned long *umap, *vmap;
   12.32 +
   12.33 +static unsigned long frames;
   12.34 +static unsigned long start_time;
   12.35 +
   12.36 +int main(int argc, char **argv)
   12.37 +{
   12.38 +	if(argc > 1) {
   12.39 +		tex_fname = argv[1];
   12.40 +	}
   12.41 +
   12.42 +	if(init() == -1) {
   12.43 +		return 1;
   12.44 +	}
   12.45 +
   12.46 +	while(!kbhit()) {
   12.47 +		display();
   12.48 +	}
   12.49 +	cleanup();
   12.50 +	return 0;
   12.51 +}
   12.52 +
   12.53 +int init(void)
   12.54 +{
   12.55 +	int i;
   12.56 +	struct palm_color *pal;
   12.57 +
   12.58 +	if(!(fbuf = malloc(WIDTH * HEIGHT))) {
   12.59 +		fprintf(stderr, "failed to allocate framebuffer\n");
   12.60 +		return -1;
   12.61 +	}
   12.62 +
   12.63 +	if(calc_tunnel_mapping() == -1) {
   12.64 +		fprintf(stderr, "failed to precalc tunnel mapping\n");
   12.65 +		return 1;
   12.66 +	}
   12.67 +
   12.68 +	if(tex_fname) {
   12.69 +		if(!(tex = load_texture(tex_fname))) {
   12.70 +			fprintf(stderr, "failed to load texture: %s\n", tex_fname);
   12.71 +			free(fbuf);
   12.72 +			return -1;
   12.73 +		}
   12.74 +
   12.75 +	} else {
   12.76 +		fprintf(stderr, "FOO\n");
   12.77 +		return -1;
   12.78 +	}
   12.79 +
   12.80 +	set_video_mode(0x13);
   12.81 +
   12.82 +	palm_build();
   12.83 +	get_texture_pixels(tex);
   12.84 +
   12.85 +	pal = palm_palette();
   12.86 +	for(i=0; i<palm_palette_size(); i++) {
   12.87 +		set_pal_entry(i, pal[i].r, pal[i].g, pal[i].b);
   12.88 +	}
   12.89 +	colrange = palm_color_range();
   12.90 +
   12.91 +	return 0;
   12.92 +}
   12.93 +
   12.94 +void cleanup(void)
   12.95 +{
   12.96 +	free_texture(tex);
   12.97 +	free(fbuf);
   12.98 +	set_video_mode(0x3);
   12.99 +}
  12.100 +
  12.101 +void display(void)
  12.102 +{
  12.103 +	static unsigned long msec;
  12.104 +
  12.105 +	unsigned int i;
  12.106 +	unsigned char voffs = msec >> 3;
  12.107 +	unsigned char uoffs = msec >> 6;
  12.108 +
  12.109 +	unsigned char *fbptr = fbuf;
  12.110 +	unsigned long *uptr = umap;
  12.111 +	unsigned long *vptr = vmap;
  12.112 +
  12.113 +	for(i=0; i<64000; i++) {
  12.114 +		unsigned long u = *uptr++;
  12.115 +		unsigned long v = *vptr++;
  12.116 +		unsigned long tx = ((((unsigned long)(u - uoffs) << 3) & 0xff) * tex->width) >> 8;
  12.117 +		unsigned long ty = (((unsigned long)(v + voffs) & 0xff) * tex->height) >> 8;
  12.118 +
  12.119 +		unsigned long base = tex->pixels[ty * tex->width + tx];
  12.120 +		long zcue_shift = colrange - (v >> 6);
  12.121 +		if(zcue_shift < 0) {
  12.122 +			zcue_shift = 0;
  12.123 +		}
  12.124 +		*fbptr++ = (unsigned char)(base + zcue_shift);
  12.125 +	}
  12.126 +
  12.127 +	copy_frame(fbuf);
  12.128 +	msec += 33;
  12.129 +}
  12.130 +
  12.131 +int calc_tunnel_mapping(void)
  12.132 +{
  12.133 +	int i, j;
  12.134 +	unsigned long *uptr, *vptr;
  12.135 +	float diag_dist = sqrt(1.33333 * 1.33333 + 1.0);
  12.136 +
  12.137 +	if(!(umap = malloc(WIDTH * HEIGHT * sizeof *umap))) {
  12.138 +		return -1;
  12.139 +	}
  12.140 +	if(!(vmap = malloc(WIDTH * HEIGHT * sizeof *umap))) {
  12.141 +		free(umap);
  12.142 +		return -1;
  12.143 +	}
  12.144 +
  12.145 +	uptr = umap;
  12.146 +	vptr = vmap;
  12.147 +
  12.148 +	for(i=0; i<HEIGHT; i++) {
  12.149 +		for(j=0; j<WIDTH; j++) {
  12.150 +			float x = ((float)j / WIDTH * 2.0 - 1.0) * 1.33333;
  12.151 +			float y = (float)i / HEIGHT * 2.0 - 1.0;
  12.152 +			float angle, z, dist;
  12.153 +
  12.154 +			if(fabs(x) > 0.00001) {
  12.155 +				angle = atan2(y, x) + M_PI;
  12.156 +			} else {
  12.157 +				angle = y < 0.0 ? M_PI / 2.0 : 3.0 * M_PI / 2.0;
  12.158 +			}
  12.159 +			dist = sqrt(x * x + y * y);
  12.160 +			z = 2.0 / dist;
  12.161 +
  12.162 +			*uptr++ = (unsigned int)(angle * 0.5 / M_PI * 255.0);
  12.163 +			*vptr++ = (unsigned int)(z * 255.0);
  12.164 +		}
  12.165 +	}
  12.166 +	return 0;
  12.167 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/wvga.c	Fri Mar 15 16:46:41 2013 +0200
    13.3 @@ -0,0 +1,75 @@
    13.4 +#include <stdio.h>
    13.5 +#include <stdlib.h>
    13.6 +#include <string.h>
    13.7 +#include "wvga.h"
    13.8 +#include "dpmi.h"
    13.9 +
   13.10 +/* VGA DAC registers used for palette setting in 8bpp modes */
   13.11 +#define VGA_DAC_STATE		0x3c7
   13.12 +#define VGA_DAC_ADDR_RD		0x3c7
   13.13 +#define VGA_DAC_ADDR_WR		0x3c8
   13.14 +#define VGA_DAC_DATA		0x3c9
   13.15 +
   13.16 +static void *framebuffer;
   13.17 +
   13.18 +int set_video_mode(int mode)
   13.19 +{
   13.20 +	struct dpmi_real_regs regs;
   13.21 +
   13.22 +	memset(&regs, 0, sizeof regs);
   13.23 +	regs.eax = mode;
   13.24 +	dpmi_real_int(0x10, &regs);
   13.25 +
   13.26 +	if(regs.eax == 0x100) {
   13.27 +		return -1;
   13.28 +	}
   13.29 +
   13.30 +	if(mode != 3) {
   13.31 +		framebuffer = (void*)dpmi_mmap((void*)0xa0000, 64000);
   13.32 +	} else {
   13.33 +		dpmi_munmap((void*)0xa0000);
   13.34 +	}
   13.35 +	return 0;
   13.36 +}
   13.37 +
   13.38 +void set_palette(int idx, int *col, int count)
   13.39 +{
   13.40 +	int i;
   13.41 +
   13.42 +	__asm {
   13.43 +		mov dx, VGA_DAC_ADDR_WR
   13.44 +		mov eax, idx
   13.45 +		out dx, al
   13.46 +	}
   13.47 +
   13.48 +	for(i=0; i<count; i++) {
   13.49 +		unsigned char r = *col++ >> 2;
   13.50 +		unsigned char g = *col++ >> 2;
   13.51 +		unsigned char b = *col++ >> 2;
   13.52 +
   13.53 +		__asm {
   13.54 +			mov dx, VGA_DAC_DATA
   13.55 +			mov al, r
   13.56 +			out dx, al
   13.57 +			mov al, g
   13.58 +			out dx, al
   13.59 +			mov al, b
   13.60 +			out dx, al
   13.61 +		}
   13.62 +	}
   13.63 +}
   13.64 +
   13.65 +void set_pal_entry(int idx, int r, int g, int b)
   13.66 +{
   13.67 +	int color[3];
   13.68 +	color[0] = r;
   13.69 +	color[1] = g;
   13.70 +	color[2] = b;
   13.71 +
   13.72 +	set_palette(idx, color, 1);
   13.73 +}
   13.74 +
   13.75 +void copy_frame(void *pixels)
   13.76 +{
   13.77 +	memcpy(framebuffer, pixels, 64000);
   13.78 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/src/wvga.h	Fri Mar 15 16:46:41 2013 +0200
    14.3 @@ -0,0 +1,10 @@
    14.4 +#ifndef WVGA_H_
    14.5 +#define WVGA_H_
    14.6 +
    14.7 +
    14.8 +int set_video_mode(int mode);
    14.9 +void set_palette(int idx, int *col, int count);
   14.10 +void set_pal_entry(int idx, int r, int g, int b);
   14.11 +void copy_frame(void *pixels);
   14.12 +
   14.13 +#endif	/* WVGA_H_ */