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