summaryrefslogtreecommitdiff
path: root/src/cRender.h
blob: 41dd0c6e3c8ecb87feaaded5f35dae5ffdb27d10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#pragma once

#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <cmath>
#include <termios.h>
#include <time.h> //clock()
#include <chrono>
#include <thread>

#ifdef __linux__
	#include <unistd.h>
	#include <sys/ioctl.h>
	#include <stdint.h>

	typedef uint32_t WORD;
#elif _WIN32
	#error "Not ported"
  #include <Windows.h>
#else
	#error "Platforn not supported"
#endif

//errors
#define _OK_ 0
#define _ERR_ 1
#define _ERR_COORDINATES_INVALID_ 2
#define _ERR_RENDER_BLOCKED_BY_CHILD_ 3
#define _ERR_SCREEN_TOO_SMALL_ 4


//Colors
#ifdef _WIN32

	#define _COL_BLACK 0x00
	#define _COL_BLUE 0x01
	#define _COL_GREEN 0x02
	#define _COL_YELLOW 0x0E
	#define _COL_RED 0x04
	#define _COL_WHITE 0x0F
	#define _COL_DARK_WHITE 0x07
	#define _COL_INTENSITY 0x08
	#define _COL_DEFAULT 0xFF

#elif __linux__

	//FG
	#define _COL_DEFAULT		 	0x00
	#define _COL_BLACK 				0x1e//30
	#define _COL_RED 					0x1f//31
	#define _COL_GREEN 				0x20//32
	#define _COL_YELLOW 			0x21//33
	#define _COL_BLUE 				0x22//34
	#define _COL_WHITE 				0x25//37

	//BG
	#define _COL_BLACK_BG 		0x1e00 + 0x0a00//30
	#define _COL_RED_BG 			0x1f00 + 0x0a00//31
	#define _COL_GREEN_BG 		0x2000 + 0x0a00//32
	#define _COL_YELLOW_BG 		0x2100 + 0x0a00//33
	#define _COL_BLUE_BG 			0x2200 + 0x0a00//34
	#define _COL_WHITE_BG 		0x2500 + 0x0a00//37

	//MOD
	#define _COL_BOLD 				0x010000
	#define _COL_UNDERLINE 		0x040000
	#define _COL_INVERSE 			0x070000

	//Not needed
	#define _COL_BOLD_OFF 		21
	#define _COL_UNDERLINE_OFF 24
	#define _COL_INVERSE_OFF 	27

#endif // __linux__

using namespace std;

struct sPos
{
	int x;
	int y;
};
/** cRender manages a framebuffer the size of the console (window) it is run in.
*
* puts console in alternate screen mode
*/
class cRender
{
public:
	/** Constructor
	* sets cBackround[][] to _backround & wColor[][] to _color
	* Resizes console window for Windows
	* Sets Size to Console Window Size for Linux. Writes Error for _sx or _sy smaller than Screen. Get by getLastError()
	*/
	cRender(char _backound, WORD _color);

	virtual ~cRender();

	/** Draws _c @ _pos in screenbuffer
	* _color can be combined by OR: (FG | BG | MOD). Anyone can be left out.
	*/
	int drawPoint(char _c, sPos _pos,  WORD _color);

	/** draws Line from _pos1 to _pos2 in screenbuffer
	*/
	int drawLine(char _c, sPos _pos1, sPos _pos2,  WORD _color);

	/** Draws Text _s @ _pos in screenbuffer
	* First char is @ _pos
	*/
	int drawText(string _s, sPos _pos, WORD _color);

	/** writes rectangle to screenbuffer
	*/
	int drawRectangle(char _border, char _fill, sPos _pos1, sPos _pos2, WORD _borderColor, WORD _fillColor);

	/** Dumps screenbuffer to stdout
	* prints changed pixels
	*/
	int render(void);

	/** clears cScreen + wColor
	* for _forceReRender == true, the bChanged[][] is set to true to force Re-Render of whole Screen
	* clear(void) calls clear(_forceReRender = false)
	*/
	int clear();
	int clear(bool _forceReRender);

	/** Returns last Error that was not returnable
	*/
	int getLastError();

	/** Returns size of screenbuffer
	*/
	sPos getSize();

	/** Time in (real) seconds between last and second to last renders
	*/
	double getFrametime();

	/** Sets target Framerate. 0 for unlimited
	*/
	void setTargetFPS(unsigned int _fps);

	/** Deactivates automatic screen size detection and forces screen size to _size
	*/
	void forceScreenSize(sPos _size);

	/** Disable Output
	*/
	void mute(bool _mute);

protected:
	/** Empty Constructor for being inheritable
	*/
	cRender();

	/** Sets screenbuffer size
	* Uses sizeX, sizeY to determine previous screenbuffer size. Do NOT change sizeX, sizeY manually!!
	*/
	void setBufferSize(sPos _size);

	bool bBlockRender;
	//* Used by children to block render function

	bool bMute;
	bool bLockScreenSize;

	char **cScreen;
	//* Pixel Map
	WORD **wColor;
	//* Color Map
	bool **bChanged;
	//* Pixel Change Map

	char cBackound;
	//* Default backround
	WORD wBackColor;
	//* Default backround color
	unsigned int sizeX, sizeY;
	//* Size of screen array

	//Timekeeping
	unsigned int uTargetFPS;
	clock_t lastRenderTime;
	double lastFrameTime;
	timespec lastRender;

#ifdef _WIN32
	HANDLE hstdout;
	CONSOLE_SCREEN_BUFFER_INFO csbi;
#endif

	WORD wDefColor;
	//* Default Color

	int iLastError;

private:
	void forceReRender();

	void setConsoleEcho(bool _enable);

	void printDebugInfo();

	void waitForFrametime();
#ifdef _WIN32
	int SetConsoleWindowSize(int x, int y);
	//Slightly adapted from: http://www.cplusplus.com/forum/windows/121444/

	void gotoxy( int x, int y );

#elif __linux__
	sPos getConsoleWindowSize();

	void setConsoleCursor(bool _enable);

	void setAlternateBufferScreen(bool _enable);
#endif
};