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 }