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 }
|