client.c: a little correction
[0verkill.git] / blit.c
blob23ee7e7375ee65ffee5d35dce05a7191dbd143c4
1 /* screenbuffer functions */
3 #include <string.h>
4 #include <stdlib.h>
5 #include <stdio.h>
7 #ifndef WIN32
8 #include "config.h"
9 #endif
10 #include "console.h"
11 #include "cfg.h"
12 #include "error.h"
15 /* screen dimensions */
16 int SCREEN_X,SCREEN_Y;
18 int SCREEN_XOFFSET,SCREEN_YOFFSET;
21 /* screenbuffer */
22 unsigned char *screen;
23 unsigned char *screen_old;
25 #ifdef TRI_D
26 unsigned char *screen2;
27 unsigned char *screen2_old;
28 #endif
30 char *line_buf;
32 /* attributes:
33 lower 4 bits=foreground
34 bits 4-7=background
36 unsigned char *screen_a;
37 unsigned char *screen_a_old;
39 #ifdef TRI_D
40 unsigned char *screen2_a;
41 unsigned char *screen2_a_old;
42 #endif
45 /* allocate memory for screenbuffer */
46 /* requires SCREEN_X and SCREEN_Y as screen size */
47 void init_blit(void)
49 line_buf=mem_alloc(SCREEN_X);
50 if (!line_buf){ERROR("Not enough memory!\n");EXIT(1);}
51 screen=mem_alloc(SCREEN_X*SCREEN_Y);
52 if (!screen){ERROR("Not enough memory!\n");EXIT(1);}
53 screen_a=mem_alloc(SCREEN_X*SCREEN_Y);
54 if (!screen_a){ERROR("Not enough memory!\n");EXIT(1);}
55 screen_old=mem_alloc(SCREEN_X*SCREEN_Y);
56 if (!screen_old){ERROR("Not enough memory!\n");EXIT(1);}
57 screen_a_old=mem_alloc(SCREEN_X*SCREEN_Y);
58 if (!screen_a_old){ERROR("Not enough memory!\n");EXIT(1);}
59 memset(screen_a_old,0,SCREEN_X*SCREEN_Y);
60 memset(screen_old,0,SCREEN_X*SCREEN_Y);
62 #ifdef TRI_D
63 if (TRI_D_ON)
65 screen2=mem_alloc(SCREEN_X*SCREEN_Y);
66 if (!screen2){ERROR("Not enough memory!\n");EXIT(1);}
67 screen2_a=mem_alloc(SCREEN_X*SCREEN_Y);
68 if (!screen2_a){ERROR("Not enough memory!\n");EXIT(1);}
69 screen2_old=mem_alloc(SCREEN_X*SCREEN_Y);
70 if (!screen2_old){ERROR("Not enough memory!\n");EXIT(1);}
71 screen2_a_old=mem_alloc(SCREEN_X*SCREEN_Y);
72 if (!screen2_a_old){ERROR("Not enough memory!\n");EXIT(1);}
73 memset(screen2_a_old,0,SCREEN_X*SCREEN_Y);
74 memset(screen2_old,0,SCREEN_X*SCREEN_Y);
76 #endif
78 SCREEN_XOFFSET=(SCREEN_X-PLAYER_WIDTH)>>1;
79 SCREEN_YOFFSET=(SCREEN_Y-PLAYER_HEIGHT)>>1;
82 void shutdown_blit(void)
84 mem_free(line_buf);
85 mem_free(screen);
86 mem_free(screen_a);
87 mem_free(screen_old);
88 mem_free(screen_a_old);
92 void clear_screen(void)
94 memset(screen_a,0,SCREEN_X*SCREEN_Y);
95 memset(screen,0,SCREEN_X*SCREEN_Y);
97 #ifdef TRI_D
98 if (TRI_D_ON)
100 memset(screen2_a,0,SCREEN_X*SCREEN_Y);
101 memset(screen2,0,SCREEN_X*SCREEN_Y);
103 #endif
107 /* resize and clear screen buffers to new dimensions stored in SCREEN_X and SCREEN_Y*/
108 void resize_screen(void)
110 c_get_size(&SCREEN_X,&SCREEN_Y);
111 line_buf=mem_realloc(line_buf,SCREEN_X);
112 if (!line_buf){ERROR("Not enough memory!\n");EXIT(1);}
113 screen=mem_realloc(screen,SCREEN_X*SCREEN_Y);
114 if (!screen){ERROR("Not enough memory!\n");EXIT(1);}
115 screen_a=mem_realloc(screen_a,SCREEN_X*SCREEN_Y);
116 if (!screen_a){ERROR("Not enough memory!\n");EXIT(1);}
117 screen_old=mem_realloc(screen_old,SCREEN_X*SCREEN_Y);
118 if (!screen_old){ERROR("Not enough memory!\n");EXIT(1);}
119 screen_a_old=mem_realloc(screen_a_old,SCREEN_X*SCREEN_Y);
120 if (!screen_a_old){ERROR("Not enough memory!\n");EXIT(1);}
121 memset(screen_a_old,0,SCREEN_X*SCREEN_Y);
122 memset(screen_old,0,SCREEN_X*SCREEN_Y);
124 #ifdef TRI_D
125 if (TRI_D_ON)
127 screen2=mem_realloc(screen2,SCREEN_X*SCREEN_Y);
128 if (!screen2){ERROR("Not enough memory!\n");EXIT(1);}
129 screen2_a=mem_realloc(screen2_a,SCREEN_X*SCREEN_Y);
130 if (!screen2_a){ERROR("Not enough memory!\n");EXIT(1);}
131 screen2_old=mem_realloc(screen2_old,SCREEN_X*SCREEN_Y);
132 if (!screen2_old){ERROR("Not enough memory!\n");EXIT(1);}
133 screen2_a_old=mem_realloc(screen2_a_old,SCREEN_X*SCREEN_Y);
134 if (!screen2_a_old){ERROR("Not enough memory!\n");EXIT(1);}
135 memset(screen2_a_old,0,SCREEN_X*SCREEN_Y);
136 memset(screen2_old,0,SCREEN_X*SCREEN_Y);
138 #endif
140 SCREEN_XOFFSET=(SCREEN_X-PLAYER_WIDTH)>>1;
141 SCREEN_YOFFSET=(SCREEN_Y-PLAYER_HEIGHT)>>1;
143 clear_screen();
147 void redraw_screen(void)
149 memset(screen_a_old,0,SCREEN_X*SCREEN_Y);
150 memset(screen_old,0,SCREEN_X*SCREEN_Y);
152 #ifdef TRI_D
153 if (TRI_D_ON)
155 memset(screen2_a_old,0,SCREEN_X*SCREEN_Y);
156 memset(screen2_old,0,SCREEN_X*SCREEN_Y);
158 #endif
160 clear_screen();
164 /* print text into screen buffer on given position, with given color */
165 void print2screen(int x,int y,unsigned char color,char *message)
167 int offs=x+SCREEN_X*y;
168 int l=strlen(message);
170 color&=15;
172 if (y>=SCREEN_Y||x>=SCREEN_X)return;
173 if (l+offs>SCREEN_X*SCREEN_Y)l=SCREEN_X*SCREEN_Y-offs;
175 memset(screen_a+offs,color,l);
176 memcpy(screen+offs,message,l);
178 #ifdef TRI_D
179 if (TRI_D_ON)
181 memset(screen2_a+offs,color,l);
182 memcpy(screen2+offs,message,l);
184 #endif
188 /* draw screenbuffer to the screen */
189 #ifdef HAVE_INLINE
190 inline void
191 #else
192 void
193 #endif
194 blit_screen(unsigned char ignore_bg)
196 int x,y,s;
197 int yof, off;
198 unsigned char a;
199 int changed=1;
200 int status_flag;
201 unsigned char *sc, *sc_old, *at, *at_old;
202 unsigned char last_color;
203 unsigned char attribute,attribute_old;
205 #ifdef TRI_D
206 sc=(TRI_D_ON&&tri_d)?screen2:screen;
207 sc_old=(TRI_D_ON&&tri_d)?screen2_old:screen_old;
208 at=(TRI_D_ON&&tri_d)?screen2_a:screen_a;
209 at_old=(TRI_D_ON&&tri_d)?screen2_a_old:screen_a_old;
210 #else
211 sc=screen;
212 sc_old=screen_old;
213 at=screen_a;
214 at_old=screen_a_old;
215 #endif
217 last_color=*at;
218 if (ignore_bg)last_color&=15;
219 c_setcolor_bg(last_color,(last_color)>>4);
220 for (y=0;y<SCREEN_Y;y++)
222 c_goto(0,y);
223 yof=SCREEN_X*y;
224 for (x=0;x<SCREEN_X;x++)
226 attribute=at[x+yof];
227 attribute_old=at_old[x+yof];
228 if (ignore_bg){attribute&=15;attribute_old&=15;}
230 if (x == SCREEN_X - 1 && y == SCREEN_Y - 1) break;
231 if (sc[x+yof]==sc_old[x+yof]&&attribute==attribute_old){changed=0;continue;}
232 if (!changed)c_goto(x,y);
233 changed=1;
235 a=(last_color^attribute);
236 status_flag= !!(a&0x07) | /* foreground */
237 ((a&0x08)>>2) | /* foreground highlight */
238 (!!(a&0x70)<<2);/* background */
240 switch(status_flag) /* what changed: */
242 case 0: /* nothing */
243 break;
245 case 1: /* foreground */
246 c_setcolor_3b(attribute);
247 break;
249 case 6: /* higlight and background */
250 case 2: /* highlight */
251 if (attribute&8) /* hlt on */
252 c_sethlt_bg((attribute>>3)&1,attribute>>4);
253 else
254 c_setcolor_bg(attribute,attribute>>4);
255 break;
257 case 7: /* background, foreground and highlight */
258 case 3: /* foreground and higlight */
259 c_setcolor_bg(attribute,attribute>>4);
260 break;
262 case 4: /* background */
263 c_setbgcolor(attribute>>4);
264 break;
266 case 5: /* background and foreground */
267 c_setcolor_3b_bg(attribute,attribute>>4);
268 break;
270 /* draw bigger pieces to screen */
271 line_buf[x] = sc[off = x + yof] ? sc[off = x + yof] : 32;
272 for (s = x++; x < SCREEN_X && at[off = x + yof] == attribute &&
273 at_old[off] == attribute_old; x++)
274 line_buf[x] = sc[off] ? sc[off] : 32;
275 last_color = attribute;
276 c_print_l(line_buf + s, x---s);
279 memcpy(sc_old,sc,SCREEN_X*SCREEN_Y);
280 memcpy(at_old,at,SCREEN_X*SCREEN_Y);
281 c_refresh();
285 /* draw frame to the screen */
286 /* x,y = upper left corner */
287 /* w,h = width and height of the content */
288 void draw_frame(int x,int y,int w,int h,unsigned char color)
290 int a;
291 char *t;
293 color&=15;
296 t=mem_alloc(w+3);
297 if (!t)return;
298 t[w+2]=0;
299 t[w]=0;
300 t[w-1]=0;
301 print2screen(x,y,color,"+");
302 print2screen(x+w+1,y,color,"+");
303 print2screen(x+w+1,y+h+1,color,"+");
304 print2screen(x,y+h+1,color,"+");
305 memset(t,'-',w);
306 print2screen(x+1,y,color,t);
307 print2screen(x+1,y+h+1,color,t);
308 memset(t,' ',w+1);
309 t[0]='|';
310 t[w+1]='|';
311 for (a=1;a<=h;a++)
312 print2screen(x,y+a,color,t);
313 mem_free(t);