1 /* screenbuffer functions */
15 /* screen dimensions */
16 int SCREEN_X
,SCREEN_Y
;
18 int SCREEN_XOFFSET
,SCREEN_YOFFSET
;
22 unsigned char *screen
;
23 unsigned char *screen_old
;
26 unsigned char *screen2
;
27 unsigned char *screen2_old
;
33 lower 4 bits=foreground
36 unsigned char *screen_a
;
37 unsigned char *screen_a_old
;
40 unsigned char *screen2_a
;
41 unsigned char *screen2_a_old
;
45 /* allocate memory for screenbuffer */
46 /* requires SCREEN_X and SCREEN_Y as screen size */
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
);
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
);
78 SCREEN_XOFFSET
=(SCREEN_X
-PLAYER_WIDTH
)>>1;
79 SCREEN_YOFFSET
=(SCREEN_Y
-PLAYER_HEIGHT
)>>1;
82 void shutdown_blit(void)
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
);
100 memset(screen2_a
,0,SCREEN_X
*SCREEN_Y
);
101 memset(screen2
,0,SCREEN_X
*SCREEN_Y
);
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
);
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
);
140 SCREEN_XOFFSET
=(SCREEN_X
-PLAYER_WIDTH
)>>1;
141 SCREEN_YOFFSET
=(SCREEN_Y
-PLAYER_HEIGHT
)>>1;
147 void redraw_screen(void)
149 memset(screen_a_old
,0,SCREEN_X
*SCREEN_Y
);
150 memset(screen_old
,0,SCREEN_X
*SCREEN_Y
);
155 memset(screen2_a_old
,0,SCREEN_X
*SCREEN_Y
);
156 memset(screen2_old
,0,SCREEN_X
*SCREEN_Y
);
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
);
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
);
181 memset(screen2_a
+offs
,color
,l
);
182 memcpy(screen2
+offs
,message
,l
);
188 /* draw screenbuffer to the screen */
194 blit_screen(unsigned char ignore_bg
)
201 unsigned char *sc
, *sc_old
, *at
, *at_old
;
202 unsigned char last_color
;
203 unsigned char attribute
,attribute_old
;
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
;
218 if (ignore_bg
)last_color
&=15;
219 c_setcolor_bg(last_color
,(last_color
)>>4);
220 for (y
=0;y
<SCREEN_Y
;y
++)
224 for (x
=0;x
<SCREEN_X
;x
++)
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
);
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 */
245 case 1: /* foreground */
246 c_setcolor_3b(attribute
);
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);
254 c_setcolor_bg(attribute
,attribute
>>4);
257 case 7: /* background, foreground and highlight */
258 case 3: /* foreground and higlight */
259 c_setcolor_bg(attribute
,attribute
>>4);
262 case 4: /* background */
263 c_setbgcolor(attribute
>>4);
266 case 5: /* background and foreground */
267 c_setcolor_3b_bg(attribute
,attribute
>>4);
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
);
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
)
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
,"+");
306 print2screen(x
+1,y
,color
,t
);
307 print2screen(x
+1,y
+h
+1,color
,t
);
312 print2screen(x
,y
+a
,color
,t
);