# HG changeset patch # User John Tsiombikas # Date 1363358801 -7200 # Node ID c525cfbfd4a238158cd6ce19caf6b3b26c916e39 initial commit diff -r 000000000000 -r c525cfbfd4a2 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,2 @@ +\.obj$ +^wtunnel.exe$ diff -r 000000000000 -r c525cfbfd4a2 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,22 @@ +obj = tunnel.obj & + wvga.obj & + dpmi.obj & + palman.obj & + texture.obj +bin = wtunnel.exe + +CC = wcc386 +CFLAGS = -fp5 -ot +LD = wlink + +$(bin): $(obj) + $(LD) name $@ file { $(obj) } $(LDFLAGS) + +.c: src\ + +.c.obj: .autodepend + $(CC) $(CFLAGS) $[* + +clean: .symbolic + del *.obj + del $(bin) diff -r 000000000000 -r c525cfbfd4a2 dos4gw.exe Binary file dos4gw.exe has changed diff -r 000000000000 -r c525cfbfd4a2 src/colorbit.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/colorbit.h Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,17 @@ +#ifndef COLORBIT_H_ +#define COLORBIT_H_ + +#define RSHIFT 0 +#define GSHIFT 8 +#define BSHIFT 16 + +#define PACK_COLOR24(r, g, b) \ + ((((r) & 0xff) << RSHIFT) | \ + (((g) & 0xff) << GSHIFT) | \ + (((b) & 0xff) << BSHIFT)) + +#define UNP_RED32(x) (((x) >> RSHIFT) & 0xff) +#define UNP_GREEN32(x) (((x) >> GSHIFT) & 0xff) +#define UNP_BLUE32(x) (((x) >> BSHIFT) & 0xff) + +#endif /* COLORBIT_H_ */ diff -r 000000000000 -r c525cfbfd4a2 src/dpmi.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dpmi.c Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,55 @@ +#include "dpmi.h" + +void dpmi_real_int(int inum, struct dpmi_real_regs *regs) +{ + unsigned char int_num = (unsigned char)inum; + __asm { + mov eax, 0x300 + mov edi, regs + mov bl, int_num + mov bh, 0 + xor ecx, ecx + int 0x31 + } +} + +void *dpmi_mmap(uint32_t phys_addr, unsigned int size) +{ + uint16_t mem_high, mem_low; + uint16_t phys_high = phys_addr >> 16; + uint16_t phys_low = phys_addr & 0xffff; + uint16_t size_high = size >> 16; + uint16_t size_low = size & 0xffff; + unsigned int err, res = 0; + + __asm { + mov eax, 0x800 + mov bx, phys_high + mov cx, phys_low + mov si, size_high + mov di, size_low + int 0x31 + add res, 1 + mov err, eax + mov mem_high, bx + mov mem_low, cx + } + + if(res == 2) { + return 0; + } + return (void*)(((uint32_t)mem_high << 16) | ((uint32_t)mem_low)); +} + +void dpmi_munmap(void *addr) +{ + uint16_t mem_high = (uint32_t)addr >> 16; + uint16_t mem_low = (uint16_t)addr; + + __asm { + mov eax, 0x801 + mov bx, mem_high + mov cx, mem_low + int 0x31 + } +} diff -r 000000000000 -r c525cfbfd4a2 src/dpmi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dpmi.h Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,26 @@ +#ifndef DPMI_H_ +#define DPMI_H_ + +#include "inttypes.h" + +struct dpmi_real_regs { + uint32_t edi, esi, ebp; + uint32_t reserved; + uint32_t ebx, edx, ecx, eax; + uint16_t flags; + uint16_t es, ds, fs, gs; + uint16_t ip, cs, sp, ss; +}; + +unsigned short dpmi_alloc(unsigned int par); +#pragma aux dpmi_alloc = \ + "mov eax, 0x100" \ + "int 0x31" \ + value[ax] parm[ebx]; + +void dpmi_real_int(int inum, struct dpmi_real_regs *regs); + +void *dpmi_mmap(uint32_t phys_addr, unsigned int size); +void dpmi_munmap(void *addr); + +#endif /* DPMI_H_ */ diff -r 000000000000 -r c525cfbfd4a2 src/inttypes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/inttypes.h Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,12 @@ +#ifndef INT_TYPES_H_ +#define INT_TYPES_H_ + +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; + +#endif /* INT_TYPES_H_ */ diff -r 000000000000 -r c525cfbfd4a2 src/palman.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/palman.c Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,124 @@ +/* +256-color 3D graphics hack for real-mode DOS. +Copyright (C) 2011 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include "palman.h" + +#define MAX_COLORS 256 +static struct palm_color colors[MAX_COLORS]; +static int base_index[MAX_COLORS]; + +static struct palm_color pal[MAX_COLORS]; +static unsigned int ncol, pcol; +static int range; + +void palm_clear(void) +{ + ncol = 0; +} + +int palm_add_color(unsigned char r, unsigned char g, unsigned char b) +{ + if(ncol >= MAX_COLORS) { + return -1; + } + colors[ncol].r = r; + colors[ncol].g = g; + colors[ncol].b = b; + ncol++; + return 0; +} + +int palm_color_index(unsigned char r, unsigned char g, unsigned char b) +{ + int i; + + for(i=0; i> 8); + pal[pcol].g = (unsigned char)(g >> 8); + pal[pcol].b = (unsigned char)(b >> 8); + pcol++; + r += dr; + g += dg; + b += db; + } + } + return pcol; +} + +struct palm_color *palm_palette(void) +{ + return pal; +} + +int palm_palette_size(void) +{ + return pcol; +} + + +int palm_color_base(unsigned char r, unsigned char g, unsigned char b) +{ + int c; + + if((c = palm_color_index(r, g, b)) == -1) { + return -1; + } + return base_index[c]; +} + +int palm_color_range(void) +{ + return range; +} diff -r 000000000000 -r c525cfbfd4a2 src/palman.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/palman.h Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,39 @@ +/* +256-color 3D graphics hack for real-mode DOS. +Copyright (C) 2011 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifndef PALMAN_H_ +#define PALMAN_H_ + +struct palm_color { + unsigned char r, g, b; +}; + +void palm_clear(void); +int palm_add_color(unsigned char r, unsigned char g, unsigned char b); +int palm_color_index(unsigned char r, unsigned char g, unsigned char b); + +int palm_build(void); + +struct palm_color *palm_palette(void); +int palm_palette_size(void); + +int palm_color_base(unsigned char r, unsigned char g, unsigned char b); +int palm_color_range(void); + + +#endif /* PALMAN_H_ */ diff -r 000000000000 -r c525cfbfd4a2 src/texture.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/texture.c Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,136 @@ +/* +256-color 3D graphics hack for real-mode DOS. +Copyright (C) 2011 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include "texture.h" +#include "palman.h" + +struct texture *load_texture(const char *fname) +{ + long i, num_pixels; + struct texture *tex; + long fpos; + + if(!(tex = malloc(sizeof *tex))) { + return 0; + } + memset(tex, 0, sizeof *tex); + + if(!(tex->file = fopen(fname, "rb"))) { + fprintf(stderr, "failed to open texture: %s\n", fname); + free_texture(tex); + return 0; + } + if(fscanf(tex->file, "P6 %d %d 255 ", &tex->width, &tex->height) != 2) { + fprintf(stderr, "invalid pixmap: %s\n", fname); + free_texture(tex); + return 0; + } + fpos = ftell(tex->file); + + num_pixels = tex->width * tex->height; + for(i=0; ifile); + g = fgetc(tex->file); + b = fgetc(tex->file); + + if(feof(tex->file)) { + fprintf(stderr, "unexpected EOF while reading: %s\n", fname); + free_texture(tex); + return 0; + } + + if(palm_color_index(r, g, b) == -1) { + palm_add_color(r, g, b); + } + } + fseek(tex->file, fpos, SEEK_SET); + return tex; +} + +void free_texture(struct texture *tex) +{ + if(tex) { + if(tex->file) { + fclose(tex->file); + } + free(tex->pixels); + free(tex); + } +} + +unsigned char *get_texture_pixels(struct texture *tex) +{ + if(!tex->pixels && tex->file) { + long i, num_pixels = tex->width * tex->height; + + if(!(tex->pixels = malloc(num_pixels))) { + return 0; + } + + for(i=0; ifile); + g = fgetc(tex->file); + b = fgetc(tex->file); + + if((base = palm_color_base(r, g, b)) == -1) { + base = 0; + } + tex->pixels[i] = base; + } + + fclose(tex->file); + tex->file = 0; + } + + return tex->pixels; +} + +struct texture *tex_gen_checker(int xsz, int ysz, int ush, int vsh, int c1, int c2) +{ + int i, j; + struct texture *tex; + unsigned char *pptr; + + if(!(tex = malloc(sizeof *tex))) { + return 0; + } + memset(tex, 0, sizeof *tex); + + if(!(tex->pixels = malloc(xsz * ysz))) { + free(tex); + return 0; + } + tex->width = xsz; + tex->height = ysz; + + pptr = tex->pixels; + for(i=0; i> vsh) & 1) == ((j >> ush) & 1) ? c1 : c2; + *pptr++ = c; + } + } + return tex; +} diff -r 000000000000 -r c525cfbfd4a2 src/texture.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/texture.h Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,41 @@ +/* +256-color 3D graphics hack for real-mode DOS. +Copyright (C) 2011 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#ifndef TEXTURE_H_ +#define TEXTURE_H_ + +struct texture { + int width, height; + unsigned char *pixels; + + struct { + unsigned char r, g, b; + } *palette; + int num_colors; + + FILE *file; +}; + +struct texture *load_texture(const char *fname); +void free_texture(struct texture *tex); + +unsigned char *get_texture_pixels(struct texture *tex); +int find_texture_color(struct texture *tex, int r, int g, int b); + +struct texture *tex_gen_checker(int xsz, int ysz, int usub, int vsub, int c1, int c2); + +#endif /* TEXTURE_H_ */ diff -r 000000000000 -r c525cfbfd4a2 src/tunnel.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tunnel.c Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include +#include "wvga.h" +#include "texture.h" +#include "palman.h" + +#ifndef M_PI +#define M_PI 3.14159265 +#endif + +#define WIDTH 320 +#define HEIGHT 200 + +int init(void); +void cleanup(void); +void display(void); +int calc_tunnel_mapping(void); + +static unsigned char *fbuf; +static struct texture *tex; +static int colrange; + +static char *tex_fname; + +static unsigned long *umap, *vmap; + +static unsigned long frames; +static unsigned long start_time; + +int main(int argc, char **argv) +{ + if(argc > 1) { + tex_fname = argv[1]; + } + + if(init() == -1) { + return 1; + } + + while(!kbhit()) { + display(); + } + cleanup(); + return 0; +} + +int init(void) +{ + int i; + struct palm_color *pal; + + if(!(fbuf = malloc(WIDTH * HEIGHT))) { + fprintf(stderr, "failed to allocate framebuffer\n"); + return -1; + } + + if(calc_tunnel_mapping() == -1) { + fprintf(stderr, "failed to precalc tunnel mapping\n"); + return 1; + } + + if(tex_fname) { + if(!(tex = load_texture(tex_fname))) { + fprintf(stderr, "failed to load texture: %s\n", tex_fname); + free(fbuf); + return -1; + } + + } else { + fprintf(stderr, "FOO\n"); + return -1; + } + + set_video_mode(0x13); + + palm_build(); + get_texture_pixels(tex); + + pal = palm_palette(); + for(i=0; i> 3; + unsigned char uoffs = msec >> 6; + + unsigned char *fbptr = fbuf; + unsigned long *uptr = umap; + unsigned long *vptr = vmap; + + for(i=0; i<64000; i++) { + unsigned long u = *uptr++; + unsigned long v = *vptr++; + unsigned long tx = ((((unsigned long)(u - uoffs) << 3) & 0xff) * tex->width) >> 8; + unsigned long ty = (((unsigned long)(v + voffs) & 0xff) * tex->height) >> 8; + + unsigned long base = tex->pixels[ty * tex->width + tx]; + long zcue_shift = colrange - (v >> 6); + if(zcue_shift < 0) { + zcue_shift = 0; + } + *fbptr++ = (unsigned char)(base + zcue_shift); + } + + copy_frame(fbuf); + msec += 33; +} + +int calc_tunnel_mapping(void) +{ + int i, j; + unsigned long *uptr, *vptr; + float diag_dist = sqrt(1.33333 * 1.33333 + 1.0); + + if(!(umap = malloc(WIDTH * HEIGHT * sizeof *umap))) { + return -1; + } + if(!(vmap = malloc(WIDTH * HEIGHT * sizeof *umap))) { + free(umap); + return -1; + } + + uptr = umap; + vptr = vmap; + + for(i=0; i 0.00001) { + angle = atan2(y, x) + M_PI; + } else { + angle = y < 0.0 ? M_PI / 2.0 : 3.0 * M_PI / 2.0; + } + dist = sqrt(x * x + y * y); + z = 2.0 / dist; + + *uptr++ = (unsigned int)(angle * 0.5 / M_PI * 255.0); + *vptr++ = (unsigned int)(z * 255.0); + } + } + return 0; +} diff -r 000000000000 -r c525cfbfd4a2 src/wvga.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/wvga.c Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,75 @@ +#include +#include +#include +#include "wvga.h" +#include "dpmi.h" + +/* VGA DAC registers used for palette setting in 8bpp modes */ +#define VGA_DAC_STATE 0x3c7 +#define VGA_DAC_ADDR_RD 0x3c7 +#define VGA_DAC_ADDR_WR 0x3c8 +#define VGA_DAC_DATA 0x3c9 + +static void *framebuffer; + +int set_video_mode(int mode) +{ + struct dpmi_real_regs regs; + + memset(®s, 0, sizeof regs); + regs.eax = mode; + dpmi_real_int(0x10, ®s); + + if(regs.eax == 0x100) { + return -1; + } + + if(mode != 3) { + framebuffer = (void*)dpmi_mmap((void*)0xa0000, 64000); + } else { + dpmi_munmap((void*)0xa0000); + } + return 0; +} + +void set_palette(int idx, int *col, int count) +{ + int i; + + __asm { + mov dx, VGA_DAC_ADDR_WR + mov eax, idx + out dx, al + } + + for(i=0; i> 2; + unsigned char g = *col++ >> 2; + unsigned char b = *col++ >> 2; + + __asm { + mov dx, VGA_DAC_DATA + mov al, r + out dx, al + mov al, g + out dx, al + mov al, b + out dx, al + } + } +} + +void set_pal_entry(int idx, int r, int g, int b) +{ + int color[3]; + color[0] = r; + color[1] = g; + color[2] = b; + + set_palette(idx, color, 1); +} + +void copy_frame(void *pixels) +{ + memcpy(framebuffer, pixels, 64000); +} diff -r 000000000000 -r c525cfbfd4a2 src/wvga.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/wvga.h Fri Mar 15 16:46:41 2013 +0200 @@ -0,0 +1,10 @@ +#ifndef WVGA_H_ +#define WVGA_H_ + + +int set_video_mode(int mode); +void set_palette(int idx, int *col, int count); +void set_pal_entry(int idx, int r, int g, int b); +void copy_frame(void *pixels); + +#endif /* WVGA_H_ */