make it possible to override CXX from the command line
[rofl0r-df-libgraphics.git] / g_src / graphics.h
blob717cc085c315b31e97fda301af75f986f365ad6b
1 #ifndef GRAPHICS_H
2 #define GRAPHICS_H
4 #include <string>
5 #include <map>
6 #include <cassert>
7 using std::string;
9 #include "g_basics.h"
10 #include "platform.h"
11 #include "basics.h"
13 enum Texture
15 TEXTURE_MOUSE,
16 TEXTURENUM
19 /* screen array layout
22 * X*Y tiles of 4 bytes each in column-major order (FIXME: This is inefficient! It should be row-major!)
23 * For each tile, byte 0 is the character, 1 is foreground color, 2 is bacground, and 3 denotes bold.
25 * As there are only 8 different colors and bold is a boolean, this leaves a lot of free space. Therefore,
26 * without involving the graphics arrays, out-of-gamut values can be used for designating TTF objects.
28 * This means setting the bold byte to all 1s (0xff), and then using the other three bytes as a designator.
30 * Time will tell whether this was a good idea or not.
33 // So yeah, we store "type" in the previously bold byte. This means we have quite a lot of free types yet.
34 #define GRAPHICSTYPE_TTF 0xff
35 // This type denotes a tile that is covered by truetype, but is not the tile it starts on.
36 #define GRAPHICSTYPE_TTFCONT 0xfe
39 class graphicst
41 int lookup_pair(std::pair<int,int> color);
42 long calculate_old_fps();
43 public:
44 long screenx,screeny;
45 char screenf,screenb;
46 char screenbright;
48 unsigned char *screen;
49 long *screentexpos;
50 char *screentexpos_addcolor;
51 unsigned char *screentexpos_grayscale;
52 unsigned char *screentexpos_cf;
53 unsigned char *screentexpos_cbr;
55 // Calling this is not enough in itself. You also need to call swap_front/back.
56 void resize(int x, int y);
58 long clipx[2],clipy[2];
59 long tex_pos[TEXTURENUM];
61 long rect_id;
63 LARGE_INTEGER print_time[100];
64 long print_index;
65 char display_frames;
67 short force_full_display_count;
69 char original_rect;
71 int dimx, dimy;
73 graphicst()
75 print_index=0;
76 display_frames=0;
77 rect_id=-1;
78 force_full_display_count=4;
79 original_rect=1;
81 screentexpos = NULL;
82 screentexpos_addcolor = NULL;
83 screentexpos_grayscale = NULL;
84 screentexpos_cf = NULL;
85 screentexpos_cbr = NULL;
86 screen = NULL;
89 void locate(long y,long x)
91 // No point in clamping here, addchar clamps too.
92 screenx=x;
93 screeny=y;
95 void changecolor(short f,short b,char bright)
97 screenf=f;
98 screenb=b;
99 screenbright=bright;
101 void addchar(unsigned char c,char advance=1)
103 /* assert (screen_limit == screen + dimy * dimx * 4); */
104 unsigned char *s = screen + screenx*dimy*4 + screeny*4;
105 if (s < screen_limit) {
106 if(screenx>=clipx[0]&&screenx<=clipx[1]&&
107 screeny>=clipy[0]&&screeny<=clipy[1])
109 *s++ = c;
110 *s++ = screenf;
111 *s++ = screenb;
112 *s++ = screenbright;
113 screentexpos[screenx*dimy + screeny]=0;
116 screenx += advance;
118 void addchar(unsigned int x, unsigned int y, unsigned char c,
119 unsigned char f, unsigned char b, unsigned char bright) {
120 /* assert (screen_limit == screen + dimy * dimx * 4); */
121 unsigned char *s = screen + x*dimy*4 + y*4;
122 if (s >= screen && s < screen_limit) {
123 if(x>=clipx[0]&&x<=clipx[1]&&
124 y>=clipy[0]&&y<=clipy[1])
126 *s++ = c;
127 *s++ = f;
128 *s++ = b;
129 *s++ = bright;
133 void addcoloredst(const char *str,const char *colorstr);
134 void addst(const string &str, justification just = justify_left, int space=0);
135 void erasescreen_clip();
136 void erasescreen();
137 void erasescreen_rect(int x1, int x2, int y1, int y2);
138 void setclipping(long x1,long x2,long y1,long y2);
140 void add_tile(long texp,char addcolor);
141 void add_tile_grayscale(long texp,char cf,char cbr);
143 void prepare_graphics(string &src_dir);
145 void gray_out_rect(long sx,long ex,long sy,long ey)
147 long x,y;
148 for(x=sx;x<=ex;x++)
150 for(y=sy;y<=ey;y++)
152 screen[x*dimy*4 + y*4 + 1]=0;
153 screen[x*dimy*4 + y*4 + 2]=7;
154 screen[x*dimy*4 + y*4 + 3]=0;
158 void dim_colors(long x,long y,char dim);
160 void rain_color_square(long x,long y);
161 void snow_color_square(long x,long y);
162 void color_square(long x,long y,unsigned char f,unsigned char b,unsigned char br);
164 long border_start_x(){return 1;}
165 long border_start_y(){return 1;}
166 long border_end_x(){return 78;}
167 long border_end_y(){return 23;}
168 long text_width(){return 1;}
169 long text_height(){return 1;}
170 long window_element_height(long minus,char border)
172 long height=25;
173 if(border)height-=2;
174 height-=text_height()*minus;
175 return height;
178 int mouse_x, mouse_y;
179 void get_mouse_text_coords(int32_t &mx, int32_t &my);
180 void draw_border(int x1, int x2, int y1, int y2);
182 // Instead of doing costly bounds-checking calculations, we cache the end
183 // of the arrays..
184 unsigned char *screen_limit;
187 extern graphicst gps;
188 // From graphics.cpp
189 void render_things();
191 // Locates some area of the screen with free space for writing
192 class gps_locator {
193 int y, last_x;
194 public:
195 gps_locator(int y, int x) {
196 this->y = y;
197 last_x = x;
199 bool is_free(int x) {
200 unsigned char c = gps.screen[x*gps.dimy*4 + y*4];
201 switch (c) {
202 case 0:
203 case 20:
204 case 176:
205 case 177:
206 case 178:
207 case 219:
208 case 254:
209 case 255:
210 return true;
211 default:
212 return false;
215 void operator()(int sz) {
216 // First, check if our cached slot will still do
217 bool ok = true;
218 for (int x = last_x; x < last_x + sz; x++)
219 if (!is_free(x)) {
220 ok = false;
221 break;
223 if (ok) {
224 // Yeah, okay
225 gps.locate(y, last_x);
226 } else {
227 // Not so okay. Find a new spot.
228 int run = 0, x = 0;
229 for (; x < gps.dimx; x++) {
230 if (is_free(x))
231 run++;
232 else run = 0;
233 if (run > sz + 2) { // We pad things a bit for cleanliness.
234 ok = true;
235 x -= sz + 1;
236 break;
239 if (ok) {
240 // Found a new spot.
241 last_x = x;
242 gps.locate(y, x);
243 } else {
244 // Damn it.
245 gps.locate(y, last_x);
251 #endif