1
- #include <stdio.h>
2
- #include <sys/ioctl.h>
1
+ #include " output.hpp "
2
+
3
3
#include < signal.h>
4
+ #include < stdio.h>
4
5
#include < string.h>
6
+ #include < sys/ioctl.h>
7
+ #include < string>
8
+ #include < vector>
9
+
10
+ // //////////////////////////
5
11
6
- typedef void (* callback_function )(void );
7
- void setOutput (callback_function drawScreen , int width , int height );
8
- void printCharXY (char c , int x , int y );
9
- void printString (char const s [], int x , int y );
10
12
int getAbsoluteX (int x);
11
13
int getAbsoluteY (int y);
12
14
int getAbsoluteCoordinate (int value, int console, int track);
13
15
int coordinatesOutOfBounds (int x, int y);
14
16
void clearScreen (void );
15
- void redrawScreen ();
16
17
void registerSigWinChCatcher (void );
17
18
void sigWinChCatcher (int signum);
18
19
void updateConsoleSize (void );
19
20
void copyArray (char dest[], const char src[], int width);
20
21
21
- /////////////////////////////
22
+ // //////////////////////////
22
23
23
24
#define PRINT_IN_CENTER 1
24
25
#define DEFAULT_WIDTH 80
@@ -33,38 +34,72 @@ int rows = DEFAULT_HEIGHT;
33
34
callback_function drawScreen;
34
35
volatile sig_atomic_t screenResized = 0 ;
35
36
36
- ///////// PUBLIC ////////////
37
+ vector<string> screenBuffer;
38
+ vector<string> onScreen;
39
+
40
+ // //////// PUBLIC //////////
37
41
38
42
void setOutput (callback_function drawScreenThat, int width, int height) {
39
43
drawScreen = drawScreenThat;
40
44
pictureWidth = width;
41
45
pictureHeight = height;
42
46
registerSigWinChCatcher ();
43
47
updateConsoleSize ();
44
- // set colors
48
+ // Set colors.
45
49
printf (" \e[%dm\e[%dm" , 37 , 40 );
46
50
}
47
51
48
- /////////////////////////
52
+ void updateScreen () {
53
+ for (size_t i = 0 ; i < screenBuffer.size (); i++) {
54
+ if (onScreen.size () <= i) {
55
+ onScreen.push_back (" " );
56
+ }
57
+ if (screenBuffer.at (i) != onScreen.at (i)) {
58
+ onScreen.at (i) = screenBuffer.at (i);
59
+ printf (" \033 [%d;%dH%s" , getAbsoluteY (i), getAbsoluteX (0 ), screenBuffer.at (i).c_str ());
60
+ }
61
+ }
62
+ }
63
+
64
+ void setBuffer (string s, int x, int y) {
65
+ int size = screenBuffer.size ();
66
+ if (size <= y) {
67
+ for (int i = size; i <= y+1 ; i++) {
68
+ screenBuffer.push_back (" " );
69
+ }
70
+ }
71
+ screenBuffer.at (y).replace (x, s.length (), s);
72
+ }
49
73
50
74
void printCharXY (char c, int x, int y) {
51
- if (coordinatesOutOfBounds (x , y ))
75
+ if (coordinatesOutOfBounds (x, y)) {
76
+ return ;
77
+ }
78
+ setBuffer (string (1 , c), x, y);
79
+ // printf("\033[%d;%dH%c", getAbsoluteY(y), getAbsoluteX(x), c);
80
+ }
81
+
82
+ void printCharImediately (char c, int x, int y) {
83
+ if (coordinatesOutOfBounds (x, y)) {
52
84
return ;
85
+ }
53
86
printf (" \033 [%d;%dH%c" , getAbsoluteY (y), getAbsoluteX (x), c);
54
87
}
55
88
56
89
void printString (char const s[], int x, int y) {
57
90
if (coordinatesOutOfBounds (x, y))
58
91
return ;
59
- int itDoesntFitTheScreen = strlen (s ) + x > columns ;
92
+ int itDoesntFitTheScreen = strlen (s) + ( unsigned ) x > ( unsigned ) columns;
60
93
if (itDoesntFitTheScreen) {
61
94
int distanceToTheRightEdge = columns - x - 1 ;
62
95
char subArray[distanceToTheRightEdge+2 ];
63
96
copyArray (subArray, s, distanceToTheRightEdge+2 );
64
97
s = subArray;
65
- printf ("\033[%d;%dH%s" , getAbsoluteY (y ), getAbsoluteX (x ), subArray );
98
+ setBuffer (subArray, x, y);
99
+ // printf("\033[%d;%dH%s", getAbsoluteY(y), getAbsoluteX(x), subArray);
66
100
} else {
67
- printf ("\033[%d;%dH%s" , getAbsoluteY (y ), getAbsoluteX (x ), s );
101
+ setBuffer (s, x, y);
102
+ // printf("\033[%d;%dH%s", getAbsoluteY(y), getAbsoluteX(x), s);
68
103
}
69
104
}
70
105
@@ -79,7 +114,7 @@ int getAbsoluteY(int y) {
79
114
int getAbsoluteCoordinate (int value, int console, int track) {
80
115
int offset = 0 ;
81
116
if (PRINT_IN_CENTER) {
82
- offset = (console - track ) / 2 ;
117
+ offset = (( console - track) / 2 ) + ((console - track) % 2 ) ;
83
118
if (offset < 0 )
84
119
offset = 0 ;
85
120
}
@@ -90,22 +125,48 @@ int coordinatesOutOfBounds(int x, int y) {
90
125
return x >= columns || y >= rows || x < 0 || y < 0 ;
91
126
}
92
127
93
-
94
- ////////// DRAW ///////////
128
+ // ///////// DRAW ///////////
129
+
130
+ void refresh () {
131
+ for (size_t i = 0 ; i < screenBuffer.size (); i++) {
132
+ if (onScreen.size () <= i) {
133
+ onScreen.push_back (" " );
134
+ }
135
+ printf (" \033 [%d;%dH%s" , getAbsoluteY (i), getAbsoluteX (0 ), screenBuffer.at (i).c_str ());
136
+ if (screenBuffer.at (i) != onScreen.at (i)) {
137
+ onScreen.at (i) = screenBuffer.at (i);
138
+ }
139
+ }
140
+ }
95
141
96
142
void clearScreen (void ) {
143
+ onScreen = {};
144
+ screenBuffer = {};
97
145
printf (" \e[1;1H\e[2J" );
98
146
}
99
147
100
- void redrawScreen () {
148
+ void refreshScreen () {
101
149
screenResized = 0 ;
102
150
updateConsoleSize ();
103
151
clearScreen ();
104
152
drawScreen ();
153
+ refresh ();
105
154
fflush (stdout);
106
155
}
107
156
108
- /////////// SIGNALS /////////////
157
+
158
+ void redrawScreen () {
159
+ if (screenResized == 1 ) {
160
+ refreshScreen ();
161
+ } else {
162
+ updateConsoleSize ();
163
+ drawScreen ();
164
+ updateScreen ();
165
+ fflush (stdout);
166
+ }
167
+ }
168
+
169
+ // /////// SIGNALS //////////
109
170
110
171
void registerSigWinChCatcher () {
111
172
struct sigaction action;
@@ -117,20 +178,24 @@ void registerSigWinChCatcher() {
117
178
sigaction (SIGWINCH, &action, NULL );
118
179
}
119
180
120
- // Fires when window size changes
181
+ /*
182
+ * Fires when window size changes.
183
+ */
121
184
void sigWinChCatcher (int signum) {
122
185
screenResized = 1 ;
123
186
}
124
187
125
- // Asks system about window size
188
+ /*
189
+ * Asks system about window size.
190
+ */
126
191
void updateConsoleSize () {
127
192
struct winsize w;
128
193
ioctl (0 , TIOCGWINSZ, &w);
129
194
columns = w.ws_col ;
130
195
rows = w.ws_row ;
131
196
}
132
197
133
- ///////// UTIL //////////
198
+ // ///////// UTIL / //////////
134
199
135
200
void copyArray (char dest[], const char src[], int width) {
136
201
int i;
0 commit comments