eobish

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