§ Произвол

Холодный термояд.
9165727cd3b39e146a83dd176b4b30f0.png
1#include <qblib.c>
2
3int     objbuf[320][200];
4float   qray[320][200];
5
6// Возвращается количество сумму пересечений с объектами
7int bzline(int x1, int y1, int x2, int y2) {
8
9    // Инициализация смещений
10    int signx  = x1 < x2 ? 1 : -1;
11    int signy  = y1 < y2 ? 1 : -1;
12    int deltax = x2 > x1 ? x2 - x1 : x1 - x2;
13    int deltay = y2 > y1 ? y2 - y1 : y1 - y2;
14    int error  = deltax - deltay;
15    int error2;
16    int match = 0;
17
18    // Перебирать до конца
19    while ((x1 != x2) || (y1 != y2)) {
20
21        // Количество пересечений
22        match += objbuf[x1][y1];
23        error2 = 2 * error;
24
25        // Коррекция по X
26        if (error2 > -deltay) {
27            error -= deltay;
28            x1 += signx;
29        }
30
31        // Коррекция по Y
32        if (error2 < deltax) {
33            error += deltax;
34            y1 += signy;
35        }
36    }
37
38    return match;
39}
40
41// Нарисовать сцену и перенести в буфер
42void draw_scene() {
43
44    for (int i = 0; i < 255; i++)
45        palette(i, i, i, i);
46
47    palette(255, 255, 0, 0);
48
49    linebf(50, 50, 100, 150, -64);
50    linebf(60, 40, 90, 120, 0);
51
52    linebf(150, 25, 200, 30, -64);
53
54    circlef(270, 125, 15, -64);
55    pset(250, 100, -64);
56
57    circlef(180, 160, 32, -128);
58    circlef(180, 160, 28, 0);
59    circlef(180, 160, 10, -64);
60
61    // Перенести нарисованные объекты в буфер
62    for (int y = 0; y < 200; y++)
63    for (int x = 0; x < 320; x++)
64        objbuf[x][y] = qb_screen[x][y];
65}
66
67// Вычисление света
68void calclight(int lx, int ly) {
69
70    for (int i = 0; i < 200; i++)
71    for (int j = 0; j < 320; j++) {
72
73        qray[j][i] = 0;
74
75        // Количество
76        int density = bzline(j, i, lx, ly);
77            density = density ? (density>>4) : 1;
78
79        // Сколько раз пересеклось с объектами
80        qray[j][i] = sqrt((lx-j)*(lx-j) + (ly-i)*(ly-i)) * sqrt(density);
81
82    }
83
84    // Перерисовка экрана
85    for (int i = 0; i < 200; i++)
86    for (int j = 0; j < 320; j++) {
87
88        // Уровень освещенности
89        int lv = 255 - (int) qray[j][i];
90
91        // Освещенность объекта
92        int cl = objbuf[j][i] + (lv < 0 ? 0 : lv);
93
94        // Поставить точку
95        pset(j, i, (cl < 0 ? 0 : (cl > 254 ? 254 : cl)));
96    }
97
98    // Курсор
99    pset(lx, ly, 255);
100}
101
102// Рисовать квадрат в буфере
103void drawbox(int x, int y, int radius, int cl) {
104
105    for (int i = -radius; i <= radius; i++)
106    for (int j = -radius; j <= radius; j++) {
107
108        int xo = x + j, yo = y + i;
109        if (xo >= 0 && xo < 320 && yo >= 0 && yo < 200) {
110            objbuf[xo][yo] = cl;
111        }
112    }
113}
114
115int main(int argc, char* argv[]) {
116
117    screen(13);
118    draw_scene();
119
120    int px = -1, py = -1, pst = 0;
121
122    // Бесконечный цикл проверки событий
123    while (sdlevent(EVT_REDRAW)) {
124
125        // Срабатывает только изменились координаты мыши
126        if (mouse.x == px && mouse.y == py && mouse.st == pst) continue;
127
128        // Нарисовать новый объект
129        if (mouse.st & LF_CLICK) drawbox(mouse.x, mouse.y, 1, 128);
130        if (mouse.st & RT_CLICK) drawbox(mouse.x, mouse.y, 1, 0);
131
132        pst = mouse.st;
133        calclight(px = mouse.x, py = mouse.y);
134    }
135
136    return 0;
137}