eobish

view src/rend.c @ 5:0baf4e98315e

depth cueing
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 19 Jan 2015 02:32:01 +0200
parents ce0548d24918
children
line source
1 #include <stdlib.h>
2 #include <string.h>
3 #include <assert.h>
4 #include "rend.h"
5 #include "player.h"
7 static void draw_tile(struct tile *tile);
9 static struct image fb;
12 int init_renderer(void)
13 {
14 return 0;
15 }
17 void shutdown_renderer(void)
18 {
19 }
21 void setup_renderer(unsigned char *pixels, int xsz, int ysz)
22 {
23 fb.xsz = xsz;
24 fb.ysz = ysz;
25 fb.pixels = pixels;
26 }
28 #define MAX_Z 5
29 #define LEFT 0
30 #define CENTER 1
31 #define RIGHT 2
33 #define CHR_TYPE 0
34 #define CHR_SIDE 1
35 #define CHR_STATE 2
36 #define CHR_Z 3
38 void render_level(struct level *lvl, int px, int py, int pdir)
39 {
40 int i, j, dx, dy, backz, clear_start, clear_end;
41 char cells[3][MAX_Z + 1];
42 struct tileset *ts = &lvl->tileset;
43 struct tile *tile;
45 dx = pdir == DIR_EAST ? 1 : (pdir == DIR_WEST ? -1 : 0);
46 dy = pdir == DIR_NORTH ? -1 : (pdir == DIR_SOUTH ? 1 : 0);
48 for(i=0; i<3; i++) { /* get 3 abreast cells ... */
49 int xoffs = (1 - i) * dy;
50 int yoffs = (i - 1) * dx;
52 for(j=0; j<MAX_Z + 1; j++) { /* ... for each depth */
53 int x = px + xoffs + dx * j;
54 int y = py + yoffs + dy * j;
56 cells[i][j] = level_cell(lvl, x, y);
57 }
58 }
60 /* draw floor and ceiling */
61 clear_start = 0;
62 clear_end = fb.ysz;
64 for(i=0; i<MAX_Z; i++) {
65 if((tile = get_tilef(ts, "ccs%d", i))) { /* ceil-center-solid-<z> */
66 draw_tile(tile);
68 if(i == MAX_Z - 1) {
69 clear_start = tile->orig_y + tile->img.ysz;
70 }
71 }
73 if((tile = get_tilef(ts, "fcs%d", i))) { /* floor-center-solid-<z> */
74 draw_tile(tile);
75 if(i == MAX_Z - 1) {
76 clear_end = tile->orig_y;
77 }
78 }
79 }
80 assert(clear_end >= clear_start);
82 /* fill the area between floor an ceiling with black */
83 memset(fb.pixels + clear_start * fb.xsz, 0, (clear_end - clear_start) * fb.xsz);
85 /* find where the back wall should go if it is within visual range
86 * and draw it ...
87 */
88 backz = -1;
89 for(i=1; i<MAX_Z + 1; i++) {
90 if(cells[CENTER][i] == '#') {
91 backz = i;
92 draw_tile(get_tilef(ts, "wcs%d", backz - 1)); /* wall-center-solid */
93 break;
94 }
95 }
96 if(backz == -1) {
97 backz = MAX_Z;
98 draw_tile(get_tilef(ts, "wco%d", backz - 1)); /* wall-center-open */
99 }
101 /* now render the walls back to front */
102 for(i=0; i<backz; i++) {
103 int z = backz - i - 1;
104 char name[] = "w---"; /* wall-<side>-<state>-<z> */
106 for(j=0; j<3; j++) {
107 int state = 's';
109 if(j == CENTER) continue; /* no walls in the center */
111 if(cells[j][z] != '#') {
112 state = 'o';
113 /* if it's an open cell, then skip drawing if the next z is also open */
114 if(z >= MAX_Z || cells[j][z + 1] != '#') continue;
115 }
117 name[CHR_SIDE] = j == LEFT ? 'l' : 'r';
118 name[CHR_STATE] = state;
119 name[CHR_Z] = z + '0';
120 draw_tile(get_tile(ts, name));
121 }
122 }
123 }
125 static void draw_tile(struct tile *tile)
126 {
127 if(!tile) return;
129 blitkey(&fb, tile->orig_x, tile->orig_y, &tile->img, 31); /* TODO unhardcode key */
130 }