eobish

changeset 5:0baf4e98315e

depth cueing
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 19 Jan 2015 02:32:01 +0200
parents ce0548d24918
children c02579c0a6c6 6a350c554e46
files src/rend.c src/tileset.c src/tileset.h utils/tileproc.c
diffstat 4 files changed, 150 insertions(+), 15 deletions(-) [+]
line diff
     1.1 --- a/src/rend.c	Sun Jan 18 13:30:30 2015 +0200
     1.2 +++ b/src/rend.c	Mon Jan 19 02:32:01 2015 +0200
     1.3 @@ -1,5 +1,6 @@
     1.4  #include <stdlib.h>
     1.5  #include <string.h>
     1.6 +#include <assert.h>
     1.7  #include "rend.h"
     1.8  #include "player.h"
     1.9  
    1.10 @@ -39,7 +40,7 @@
    1.11  	int i, j, dx, dy, backz, clear_start, clear_end;
    1.12  	char cells[3][MAX_Z + 1];
    1.13  	struct tileset *ts = &lvl->tileset;
    1.14 -	struct tile *tile_ceil, *tile_floor;
    1.15 +	struct tile *tile;
    1.16  
    1.17  	dx = pdir == DIR_EAST ? 1 : (pdir == DIR_WEST ? -1 : 0);
    1.18  	dy = pdir == DIR_NORTH ? -1 : (pdir == DIR_SOUTH ? 1 : 0);
    1.19 @@ -57,14 +58,28 @@
    1.20  	}
    1.21  
    1.22  	/* draw floor and ceiling */
    1.23 -	tile_ceil = get_tile(ts, "ceil");
    1.24 -	tile_floor = get_tile(ts, "floor");
    1.25 +	clear_start = 0;
    1.26 +	clear_end = fb.ysz;
    1.27  
    1.28 -	clear_start = tile_ceil ? tile_ceil->orig_y + tile_ceil->img.ysz : 0;
    1.29 -	clear_end = tile_floor ? tile_floor->orig_y : fb.ysz;
    1.30 +	for(i=0; i<MAX_Z; i++) {
    1.31 +		if((tile = get_tilef(ts, "ccs%d", i))) { /* ceil-center-solid-<z> */
    1.32 +			draw_tile(tile);
    1.33  
    1.34 -	draw_tile(tile_ceil);
    1.35 -	draw_tile(tile_floor);
    1.36 +			if(i == MAX_Z - 1) {
    1.37 +				clear_start = tile->orig_y + tile->img.ysz;
    1.38 +			}
    1.39 +		}
    1.40 +
    1.41 +		if((tile = get_tilef(ts, "fcs%d", i))) { /* floor-center-solid-<z> */
    1.42 +			draw_tile(tile);
    1.43 +			if(i == MAX_Z - 1) {
    1.44 +				clear_end = tile->orig_y;
    1.45 +			}
    1.46 +		}
    1.47 +	}
    1.48 +	assert(clear_end >= clear_start);
    1.49 +
    1.50 +	/* fill the area between floor an ceiling with black */
    1.51  	memset(fb.pixels + clear_start * fb.xsz, 0, (clear_end - clear_start) * fb.xsz);
    1.52  
    1.53  	/* find where the back wall should go if it is within visual range
    1.54 @@ -73,21 +88,17 @@
    1.55  	backz = -1;
    1.56  	for(i=1; i<MAX_Z + 1; i++) {
    1.57  		if(cells[CENTER][i] == '#') {
    1.58 -			char name[] = "wcs ";	/* wall-center-solid */
    1.59  			backz = i;
    1.60 -			name[CHR_Z] = backz + '0' - 1;
    1.61 -			draw_tile(get_tile(ts, name));
    1.62 +			draw_tile(get_tilef(ts, "wcs%d", backz - 1)); /* wall-center-solid */
    1.63  			break;
    1.64  		}
    1.65  	}
    1.66  	if(backz == -1) {
    1.67 -		char name[] = "wco ";	/* wall-center-open */
    1.68  		backz = MAX_Z;
    1.69 -		name[CHR_Z] = backz + '0' - 1;
    1.70 -		draw_tile(get_tile(ts, name));
    1.71 +		draw_tile(get_tilef(ts, "wco%d", backz - 1));	/* wall-center-open */
    1.72  	}
    1.73  
    1.74 -	/* now render back to front */
    1.75 +	/* now render the walls back to front */
    1.76  	for(i=0; i<backz; i++) {
    1.77  		int z = backz - i - 1;
    1.78  		char name[] = "w---";	/* wall-<side>-<state>-<z> */
     2.1 --- a/src/tileset.c	Sun Jan 18 13:30:30 2015 +0200
     2.2 +++ b/src/tileset.c	Mon Jan 19 02:32:01 2015 +0200
     2.3 @@ -1,6 +1,7 @@
     2.4  #include <stdio.h>
     2.5  #include <stdlib.h>
     2.6  #include <string.h>
     2.7 +#include <stdarg.h>
     2.8  #include <errno.h>
     2.9  #include <ctype.h>
    2.10  #include <assert.h>
    2.11 @@ -198,7 +199,7 @@
    2.12  
    2.13  	printf("loaded tileset %s\n", fname);
    2.14  	for(i=0; i<ntiles; i++) {
    2.15 -		printf("  tile: %s\n", ts->tile[i].name);
    2.16 +		printf("  tile: %s (orig: %d,%d)\n", ts->tile[i].name, ts->tile[i].orig_x, ts->tile[i].orig_y);
    2.17  	}
    2.18  
    2.19  	return 0;
    2.20 @@ -240,6 +241,19 @@
    2.21  	return bsearch(&key, ts->tile, ts->num_tiles, sizeof *ts->tile, tilecmp);
    2.22  }
    2.23  
    2.24 +struct tile *get_tilef(struct tileset *ts, const char *fmt, ...)
    2.25 +{
    2.26 +	va_list ap;
    2.27 +	int sz = strlen(fmt) * 2;
    2.28 +	char *buf = alloca(sz + 1);
    2.29 +
    2.30 +	va_start(ap, fmt);
    2.31 +	vsnprintf(buf, sz, fmt, ap);
    2.32 +	va_end(ap);
    2.33 +
    2.34 +	return get_tile(ts, buf);
    2.35 +}
    2.36 +
    2.37  static struct orig_node *load_origin_list(const char *fname)
    2.38  {
    2.39  	FILE *fp;
     3.1 --- a/src/tileset.h	Sun Jan 18 13:30:30 2015 +0200
     3.2 +++ b/src/tileset.h	Mon Jan 19 02:32:01 2015 +0200
     3.3 @@ -21,5 +21,6 @@
     3.4  void destroy_tileset(struct tileset *ts);
     3.5  
     3.6  struct tile *get_tile(struct tileset *ts, const char *name);
     3.7 +struct tile *get_tilef(struct tileset *ts, const char *fmt, ...);
     3.8  
     3.9  #endif	/* TILESET_H_ */
     4.1 --- a/utils/tileproc.c	Sun Jan 18 13:30:30 2015 +0200
     4.2 +++ b/utils/tileproc.c	Mon Jan 19 02:32:01 2015 +0200
     4.3 @@ -1,6 +1,7 @@
     4.4  #include <stdio.h>
     4.5  #include <stdlib.h>
     4.6  #include <string.h>
     4.7 +#include <ctype.h>
     4.8  #include <math.h>
     4.9  #include <float.h>
    4.10  #include <errno.h>
    4.11 @@ -16,16 +17,22 @@
    4.12  	struct palentry *next;
    4.13  };
    4.14  
    4.15 +void print_usage(const char *argv0);
    4.16  int load_palette(const char *fname);
    4.17 +int save_palette(const char *fname);
    4.18  int proc_tile(const char *fname);
    4.19  float find_nearest(float r, float g, float b);
    4.20  
    4.21  struct palentry *palette;
    4.22  int palsize;
    4.23 +float colscale[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    4.24 +int scale_count = 0;
    4.25 +int key = -1;
    4.26  
    4.27  int main(int argc, char **argv)
    4.28  {
    4.29  	int i;
    4.30 +	const char *outpalname = 0;
    4.31  
    4.32  	for(i=1; i<argc; i++) {
    4.33  		if(argv[i][0] == '-') {
    4.34 @@ -36,8 +43,45 @@
    4.35  				}
    4.36  				break;
    4.37  
    4.38 +			case 'P':
    4.39 +				outpalname = argv[++i];
    4.40 +				break;
    4.41 +
    4.42 +			case 'f':
    4.43 +				{
    4.44 +					int idx, maxcol;
    4.45 +					if(sscanf(argv[++i], "%d=%d", &idx, &maxcol) != 2) {
    4.46 +						fprintf(stderr, "-f option expects <Z>=<MAX COLOR> pairs\n");
    4.47 +						return 1;
    4.48 +					}
    4.49 +					if(idx < 0 || idx >= 10) {
    4.50 +						fprintf(stderr, "-f expects a z value from 0 to 9\n");
    4.51 +						return 1;
    4.52 +					}
    4.53 +					colscale[idx] = (float)maxcol / 255.0;
    4.54 +					if(idx >= scale_count) scale_count = idx + 1;
    4.55 +				}
    4.56 +				break;
    4.57 +
    4.58 +			case 'k':
    4.59 +				{
    4.60 +					char *endp;
    4.61 +					long x = strtol(argv[++i], &endp, 10);
    4.62 +					if(endp == argv[i]) {
    4.63 +						fprintf(stderr, "-k must be followed by a palette index\n");
    4.64 +						return 1;
    4.65 +					}
    4.66 +					key = x;
    4.67 +				}
    4.68 +				break;
    4.69 +
    4.70 +			case 'h':
    4.71 +				print_usage(argv[0]);
    4.72 +				return 0;
    4.73 +
    4.74  			default:
    4.75  				fprintf(stderr, "invalid option: %s\n", argv[i]);
    4.76 +				print_usage(argv[0]);
    4.77  				return 1;
    4.78  			}
    4.79  		} else {
    4.80 @@ -46,9 +90,27 @@
    4.81  			}
    4.82  		}
    4.83  	}
    4.84 +
    4.85 +	if(outpalname) {
    4.86 +		if(save_palette(outpalname) == -1) {
    4.87 +			fprintf(stderr, "failed to write extended palette: %s\n", outpalname);
    4.88 +			return 1;
    4.89 +		}
    4.90 +	}
    4.91 +
    4.92  	return 0;
    4.93  }
    4.94  
    4.95 +void print_usage(const char *argv0)
    4.96 +{
    4.97 +	printf("Usage: %s <options> [img1 img2 img3 ... imgN]\n", argv0);
    4.98 +	printf("Options:\n");
    4.99 +	printf("  -p <file>  use palette from file\n");
   4.100 +	printf("  -f <z>=<b> darken the image (max brightness 'b') based on the digit (z) in its filename\n");
   4.101 +	printf("  -k <idx>   colorkey index (preserve this color regardless of depth cues)\n");
   4.102 +	printf("  -h         print usage and exit\n");
   4.103 +}
   4.104 +
   4.105  int load_palette(const char *fname)
   4.106  {
   4.107  	FILE *fp;
   4.108 @@ -133,6 +195,40 @@
   4.109  	return -1;
   4.110  }
   4.111  
   4.112 +int save_palette(const char *fname)
   4.113 +{
   4.114 +	FILE *fp;
   4.115 +	int i, j;
   4.116 +	int extsize = palsize * scale_count;
   4.117 +
   4.118 +	printf("saving extended palette: %s\n", fname);
   4.119 +
   4.120 +	if(!(fp = fopen(fname, "w"))) {
   4.121 +		fprintf(stderr, "failed to save extended palette: %s: %s\n", fname, strerror(errno));
   4.122 +		return -1;
   4.123 +	}
   4.124 +
   4.125 +	if(extsize > 256) {
   4.126 +		fprintf(stderr, "warning: extended palette size too large (%d)\n", extsize);
   4.127 +	}
   4.128 +
   4.129 +	for(i=0; i<scale_count; i++) {
   4.130 +		for(j=0; j<palsize; j++) {
   4.131 +			int r = (int)(palette[j].r * colscale[i] * 255.0);
   4.132 +			int g = (int)(palette[j].g * colscale[i] * 255.0);
   4.133 +			int b = (int)(palette[j].b * colscale[i] * 255.0);
   4.134 +
   4.135 +			if(r > 255) r = 255;
   4.136 +			if(g > 255) g = 255;
   4.137 +			if(b > 255) b = 255;
   4.138 +
   4.139 +			fprintf(fp, "#%02x%02x%02x\n", r, g, b);
   4.140 +		}
   4.141 +	}
   4.142 +	fclose(fp);
   4.143 +	return 0;
   4.144 +}
   4.145 +
   4.146  int proc_tile(const char *fname)
   4.147  {
   4.148  	int i;
   4.149 @@ -141,6 +237,7 @@
   4.150  	char *outfname, *cptr;
   4.151  	FILE *fp;
   4.152  	const char *magic = "TILEIMAG";
   4.153 +	int zidx = -1;
   4.154  
   4.155  	outfname = alloca(strlen(fname) + 4);
   4.156  	strcpy(outfname, fname);
   4.157 @@ -149,6 +246,12 @@
   4.158  	}
   4.159  	strcat(outfname, ".til");
   4.160  
   4.161 +	cptr = outfname + strlen(outfname) - 1;
   4.162 +	while(cptr >= outfname && !isdigit(*cptr)) --cptr;
   4.163 +	if(cptr >= outfname) {
   4.164 +		zidx = *cptr - '0';
   4.165 +	}
   4.166 +
   4.167  	printf("processing tile: %s -> %s\n", fname, outfname);
   4.168  
   4.169  	if(!(pixels = img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGB24))) {
   4.170 @@ -168,6 +271,12 @@
   4.171  	pptr = pixels;
   4.172  	for(i=0; i<xsz * ysz; i++) {
   4.173  		int idx = find_nearest(pptr[0] / 255.0, pptr[1] / 255.0, pptr[2] / 255.0);
   4.174 +
   4.175 +		if(zidx > 0 && idx != key) {
   4.176 +			/* shift the indices to the appropriate copy of the palette */
   4.177 +			idx += zidx * palsize;
   4.178 +		}
   4.179 +
   4.180  		fputc(idx, fp);
   4.181  		pptr += 3;
   4.182  	}