eobish
diff src/rend.c @ 4:ce0548d24918
mostly works
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 18 Jan 2015 13:30:30 +0200 |
parents | |
children | 0baf4e98315e |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/rend.c Sun Jan 18 13:30:30 2015 +0200 1.3 @@ -0,0 +1,119 @@ 1.4 +#include <stdlib.h> 1.5 +#include <string.h> 1.6 +#include "rend.h" 1.7 +#include "player.h" 1.8 + 1.9 +static void draw_tile(struct tile *tile); 1.10 + 1.11 +static struct image fb; 1.12 + 1.13 + 1.14 +int init_renderer(void) 1.15 +{ 1.16 + return 0; 1.17 +} 1.18 + 1.19 +void shutdown_renderer(void) 1.20 +{ 1.21 +} 1.22 + 1.23 +void setup_renderer(unsigned char *pixels, int xsz, int ysz) 1.24 +{ 1.25 + fb.xsz = xsz; 1.26 + fb.ysz = ysz; 1.27 + fb.pixels = pixels; 1.28 +} 1.29 + 1.30 +#define MAX_Z 5 1.31 +#define LEFT 0 1.32 +#define CENTER 1 1.33 +#define RIGHT 2 1.34 + 1.35 +#define CHR_TYPE 0 1.36 +#define CHR_SIDE 1 1.37 +#define CHR_STATE 2 1.38 +#define CHR_Z 3 1.39 + 1.40 +void render_level(struct level *lvl, int px, int py, int pdir) 1.41 +{ 1.42 + int i, j, dx, dy, backz, clear_start, clear_end; 1.43 + char cells[3][MAX_Z + 1]; 1.44 + struct tileset *ts = &lvl->tileset; 1.45 + struct tile *tile_ceil, *tile_floor; 1.46 + 1.47 + dx = pdir == DIR_EAST ? 1 : (pdir == DIR_WEST ? -1 : 0); 1.48 + dy = pdir == DIR_NORTH ? -1 : (pdir == DIR_SOUTH ? 1 : 0); 1.49 + 1.50 + for(i=0; i<3; i++) { /* get 3 abreast cells ... */ 1.51 + int xoffs = (1 - i) * dy; 1.52 + int yoffs = (i - 1) * dx; 1.53 + 1.54 + for(j=0; j<MAX_Z + 1; j++) { /* ... for each depth */ 1.55 + int x = px + xoffs + dx * j; 1.56 + int y = py + yoffs + dy * j; 1.57 + 1.58 + cells[i][j] = level_cell(lvl, x, y); 1.59 + } 1.60 + } 1.61 + 1.62 + /* draw floor and ceiling */ 1.63 + tile_ceil = get_tile(ts, "ceil"); 1.64 + tile_floor = get_tile(ts, "floor"); 1.65 + 1.66 + clear_start = tile_ceil ? tile_ceil->orig_y + tile_ceil->img.ysz : 0; 1.67 + clear_end = tile_floor ? tile_floor->orig_y : fb.ysz; 1.68 + 1.69 + draw_tile(tile_ceil); 1.70 + draw_tile(tile_floor); 1.71 + memset(fb.pixels + clear_start * fb.xsz, 0, (clear_end - clear_start) * fb.xsz); 1.72 + 1.73 + /* find where the back wall should go if it is within visual range 1.74 + * and draw it ... 1.75 + */ 1.76 + backz = -1; 1.77 + for(i=1; i<MAX_Z + 1; i++) { 1.78 + if(cells[CENTER][i] == '#') { 1.79 + char name[] = "wcs "; /* wall-center-solid */ 1.80 + backz = i; 1.81 + name[CHR_Z] = backz + '0' - 1; 1.82 + draw_tile(get_tile(ts, name)); 1.83 + break; 1.84 + } 1.85 + } 1.86 + if(backz == -1) { 1.87 + char name[] = "wco "; /* wall-center-open */ 1.88 + backz = MAX_Z; 1.89 + name[CHR_Z] = backz + '0' - 1; 1.90 + draw_tile(get_tile(ts, name)); 1.91 + } 1.92 + 1.93 + /* now render back to front */ 1.94 + for(i=0; i<backz; i++) { 1.95 + int z = backz - i - 1; 1.96 + char name[] = "w---"; /* wall-<side>-<state>-<z> */ 1.97 + 1.98 + for(j=0; j<3; j++) { 1.99 + int state = 's'; 1.100 + 1.101 + if(j == CENTER) continue; /* no walls in the center */ 1.102 + 1.103 + if(cells[j][z] != '#') { 1.104 + state = 'o'; 1.105 + /* if it's an open cell, then skip drawing if the next z is also open */ 1.106 + if(z >= MAX_Z || cells[j][z + 1] != '#') continue; 1.107 + } 1.108 + 1.109 + name[CHR_SIDE] = j == LEFT ? 'l' : 'r'; 1.110 + name[CHR_STATE] = state; 1.111 + name[CHR_Z] = z + '0'; 1.112 + draw_tile(get_tile(ts, name)); 1.113 + } 1.114 + } 1.115 +} 1.116 + 1.117 +static void draw_tile(struct tile *tile) 1.118 +{ 1.119 + if(!tile) return; 1.120 + 1.121 + blitkey(&fb, tile->orig_x, tile->orig_y, &tile->img, 31); /* TODO unhardcode key */ 1.122 +}