eobish

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