1 /* OpenCP Module Player
2  * copyright (c) '94-'10 Niklas Beisert <nbeisert@physik.tu-muenchen.de>
3  * copyright (c) '04-'21 Stian Skjelstad <stian.skjelstad@gmail.com>
4  *
5  * Routines for screen output
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  * revision history: (please note changes here)
22  *  -nb980510   Niklas Beisert <nbeisert@physik.tu-muenchen.de>
23  *    -first release
24  *  -kb980717   Tammo Hinrichs <kb@nwn.de>
25  *    -did a LOT to avoid redundant mode switching (really needed with
26  *     today's monitors)
27  *    -added color look-up table for redefining the palette
28  *    -added MDA output mode for all Hercules enthusiasts out there
29  *     (really rocks in Windows 95 background :)
30  *  -fd981220   Felix Domke    <tmbinc@gmx.net>
31  *    -faked in a LFB-mode (required some other changes)
32  *  -doj20020418 Dirk Jagdmann <doj@cubic.org>
33  *    -added screenshot routines
34  *  -ss040613   Stian Skjelstad <stian@nixia.no>
35  *    -more or less killed the entire file due to the unix implementation, but
36  *     the generic functions is still kept in this file.
37  */
38 
39 #define _CONSOLE_DRIVER
40 #include "config.h"
41 #include <string.h>
42 #include "types.h"
43 #include "pfonts.h"
44 #include "imsrtns.h"
45 #include "poutput.h"
46 
47 unsigned char plpalette[256];
48 int plScrLineBytes;
49 int plScrLines;
50 
51 FontSizeEnum plCurrentFont;
52 const struct FontSizeInfo_t FontSizeInfo[] =
53 {
54 	{4, 4},
55 	{8, 8},
56 	{8, 16}
57 };
58 
59 
make_title(char * part)60 void make_title(char *part)
61 {
62 	uint16_t sbuf[CONSOLE_MAX_X];
63 	char *verstr="opencp v" VERSION;
64 
65 	fillstr(sbuf, 0, 0x30, 0, CONSOLE_MAX_X);
66 	writestring(sbuf, 2, 0x30, verstr, strlen(verstr));
67 	if (plScrWidth<100)
68 		writestring(sbuf, plScrWidth-58, 0x30, part, strlen(part));
69 	else
70 		writestring(sbuf, (plScrWidth-strlen(part))/2, 0x30, part, strlen(part));
71 	writestring(sbuf, plScrWidth-30, 0x30, "(c) 1994-2021 Stian Skjelstad", 29);
72 	_displaystrattr(0, 0, sbuf, plScrWidth);
73 }
74 
convnum(unsigned long num,char * buf,unsigned char radix,unsigned short len,char clip0)75 char *convnum(unsigned long num, char *buf, unsigned char radix, unsigned short len, char clip0)
76 {
77 	int i;
78 	for (i=0; i<len; i++)
79 	{
80 		buf[len-1-i]="0123456789ABCDEF"[num%radix];
81 		num/=radix;
82 	}
83 	buf[len]=0;
84 	if (clip0)
85 		for (i=0; i<(len-1); i++)
86 		{
87 			if (buf[i]!='0')
88 				break;
89 			buf[i]=' ';
90 		}
91 	return buf;
92 }
93 
writenum(uint16_t * buf,unsigned short ofs,unsigned char attr,unsigned long num,unsigned char radix,unsigned short len,char clip0)94 void writenum(uint16_t *buf, unsigned short ofs, unsigned char attr, unsigned long num, unsigned char radix, unsigned short len, char clip0)
95 {
96 	char convbuf[20];
97 	uint16_t *p=buf+ofs;
98 	char *cp=convbuf+len;
99 	int i;
100 	for (i=0; i<len; i++)
101 	{
102 		*--cp="0123456789ABCDEF"[num%radix];
103 		num/=radix;
104 	}
105 	for (i=0; i<len; i++)
106 	{
107 		if (clip0&&(convbuf[i]=='0')&&(i!=(len-1)))
108 		{
109 			*p++=' '|(attr<<8);
110 			cp++;
111 		} else {
112 			*p++=(*cp++)|(attr<<8);
113 			clip0=0;
114 		}
115 	}
116 }
117 
writestring(uint16_t * buf,unsigned short ofs,unsigned char attr,const char * str,unsigned short len)118 void writestring(uint16_t *buf, unsigned short ofs, unsigned char attr, const char *str, unsigned short len)
119 {
120 	uint16_t *p=buf+ofs;
121 	int i;
122 	for (i=0; i<len; i++)
123 	{
124 		*p++=(*((unsigned char *)(str)))|(attr<<8);
125 		if (*str)
126 			str++;
127 	}
128 }
129 
writestringattr(uint16_t * buf,unsigned short ofs,const uint16_t * str,unsigned short len)130 void writestringattr(uint16_t *buf, unsigned short ofs, const uint16_t *str, unsigned short len)
131 {
132 	memcpyb(buf+ofs, (void *)str, len*2);
133 }
134 
135 
markstring(uint16_t * buf,unsigned short ofs,unsigned short len)136 void markstring(uint16_t *buf, unsigned short ofs, unsigned short len)
137 {
138 	int i;
139 	buf+=ofs;
140 	for (i=0; i<len; i++)
141 		*buf++^=0x8000;
142 }
143 
fillstr(uint16_t * buf,const unsigned short ofs,const unsigned char chr,const unsigned char attr,unsigned short len)144 void fillstr(uint16_t *buf, const unsigned short ofs, const unsigned char chr, const unsigned char attr, unsigned short len)
145 {
146 	buf+=ofs;
147 	while(len)
148 	{
149 		*buf=(chr<<8)+attr;
150 		buf++;
151 		len--;
152 	}
153 
154 }
155 
generic_gdrawchar8(unsigned short x,unsigned short y,unsigned char c,unsigned char f,unsigned char b)156 void generic_gdrawchar8(unsigned short x, unsigned short y, unsigned char c, unsigned char f, unsigned char b)
157 {
158 	unsigned char *cp=plFont88[c];
159 	unsigned long p=y*plScrLineBytes+x;
160 	uint8_t *scr;
161 	short i,j;
162 
163 	scr=plVidMem+p;
164 
165 	f=plpalette[f]&0x0f;
166 	b=plpalette[b]&0x0f;
167 
168 	for (i=0; i<8; i++)
169 	{
170 		unsigned char bitmap=*cp++;
171 		for (j=0; j<8; j++)
172 		{
173 			*scr++=(bitmap&128)?f:b;
174 			bitmap<<=1;
175 		}
176 		scr+=plScrLineBytes-8;
177 	}
178 }
179 
generic_gdrawchar8t(unsigned short x,unsigned short y,unsigned char c,unsigned char f)180 void generic_gdrawchar8t(unsigned short x, unsigned short y, unsigned char c, unsigned char f)
181 {
182 	unsigned char *cp=plFont88[c];
183 	unsigned long p=y*plScrLineBytes+x;
184 	uint8_t *scr;
185 	short i,j;
186 
187 	scr=plVidMem+p;
188 
189 	f=plpalette[f]&0x0f;
190 
191 	for (i=0; i<8; i++)
192 	{
193 		unsigned char bitmap=*cp++;
194 		for (j=0; j<8; j++)
195 		{
196 			if (bitmap&128)
197 				*scr=f;
198 			scr++;
199 			bitmap<<=1;
200 		}
201 		scr+=plScrLineBytes-8;
202 	}
203 }
204 
generic_gdrawchar8p(unsigned short x,unsigned short y,unsigned char c,unsigned char f,void * picp)205 void generic_gdrawchar8p(unsigned short x, unsigned short y, unsigned char c, unsigned char f, void *picp)
206 {
207 	unsigned char *cp=plFont88[c];
208 	unsigned long p=y*plScrLineBytes+x;
209 	uint8_t *scr;
210 	uint8_t *pic;
211 	short i,j;
212 
213 	if (!picp)
214 	{
215 		_gdrawchar8(x,y,c,f,0);
216 		return;
217 	}
218 
219 	f=plpalette[f]&0x0f;
220 	scr=plVidMem+p;
221 	pic=(uint8_t *)picp+p;
222 
223 	for (i=0; i<8; i++)
224 	{
225 		unsigned char bitmap=*cp++;
226 		for (j=0; j<8; j++)
227 		{
228 			if (bitmap&128)
229 				*scr=f;
230 			else
231 				*scr=*pic;
232 			scr++;
233 			pic++;
234 			bitmap<<=1;
235 		}
236 		scr+=plScrLineBytes-8;
237 		pic+=plScrLineBytes-8;
238 	}
239 }
240 
generic_gdrawstr(unsigned short y,unsigned short x,const char * str,unsigned short len,unsigned char f,unsigned char b)241 void generic_gdrawstr(unsigned short y, unsigned short x, const char *str, unsigned short len, unsigned char f, unsigned char b)
242 {
243 	unsigned long p=16*y*plScrLineBytes+x*8;
244 	uint8_t *sp;
245 	short i,j,k;
246 
247 	sp=plVidMem+p;
248 
249 	f=plpalette[f]&0x0f;
250 	b=plpalette[b]&0x0f;
251 	for (i=0; i<16; i++)
252 	{
253 		const unsigned char *s=(unsigned char *)str;
254 		for (k=0; k<len; k++)
255 		{
256 			unsigned char bitmap=plFont816[*s][i];
257 			for (j=0; j<8; j++)
258 			{
259 				*sp++=(bitmap&128)?f:b;
260 				bitmap<<=1;
261 			}
262 			if (*s)
263 				s++;
264 		}
265 		sp+=plScrLineBytes-8*len;
266 	}
267 }
268 
generic_gdrawcharp(unsigned short x,unsigned short y,unsigned char c,unsigned char f,void * picp)269 void generic_gdrawcharp(unsigned short x, unsigned short y, unsigned char c, unsigned char f, void *picp)
270 {
271 
272 	unsigned char *cp=plFont816[c];
273 	unsigned long p=y*plScrLineBytes+x;
274 	uint8_t *pic=(uint8_t *)picp+p;
275 	uint8_t *scr;
276 	short i,j;
277 
278 	if (!picp)
279 	{
280 		_gdrawchar(x,y,c,f,0);
281 		return;
282 	}
283 
284 	scr=plVidMem+p;
285 
286 	f=plpalette[f]&0x0f;
287 
288 	for (i=0; i<16; i++)
289 	{
290 		unsigned char bitmap=*cp++;
291 		for (j=0; j<8; j++)
292 		{
293 			if (bitmap&128)
294 				*scr=f;
295 			else
296 				*scr=*pic;
297 			scr++;
298 			pic++;
299 			bitmap<<=1;
300 		}
301 		pic+=plScrLineBytes-8;
302 		scr+=plScrLineBytes-8;
303 	}
304 }
305 
generic_gdrawchar(unsigned short x,unsigned short y,unsigned char c,unsigned char f,unsigned char b)306 void generic_gdrawchar(unsigned short x, unsigned short y, unsigned char c, unsigned char f, unsigned char b)
307 {
308 	unsigned char *cp=plFont816[c];
309 	unsigned long p=y*plScrLineBytes+x;
310 	uint8_t *scr;
311 	short i,j;
312 
313 	f=plpalette[f]&0x0f;
314 	b=plpalette[b]&0x0f;
315 	scr=plVidMem+p;
316 
317 	for (i=0; i<16; i++)
318 	{
319 		unsigned char bitmap=*cp++;
320 		for (j=0; j<8; j++)
321 		{
322 			*scr++=(bitmap&128)?f:b;
323 			bitmap<<=1;
324 		}
325 		scr+=plScrLineBytes-8;
326 	}
327 }
328 
generic_gupdatestr(unsigned short y,unsigned short x,const uint16_t * str,unsigned short len,uint16_t * old)329 void generic_gupdatestr(unsigned short y, unsigned short x, const uint16_t *str, unsigned short len, uint16_t *old)
330 {
331 	unsigned long p=16*y*plScrLineBytes+x*8;
332 	uint8_t *sp;
333 	short i,j,k;
334 
335 	sp=plVidMem+p;
336 
337 	for (k=0; k<len; k++, str++, old++)
338 		if (*str!=*old)
339 		{
340 			uint8_t a = (*str)>>8;
341 			unsigned char *bitmap0=plFont816[(*str)&0xff];
342 			unsigned char f=plpalette[a]&0x0F;
343 			unsigned char b=plpalette[a]>>4;
344 			*old=*str;
345 
346 			for (i=0; i<16; i++)
347 			{
348 				unsigned char bitmap=bitmap0[i];
349 				for (j=0; j<8; j++)
350 				{
351 					*sp++=(bitmap&128)?f:b;
352 					bitmap<<=1;
353 				}
354 				sp+=plScrLineBytes-8;
355 			}
356 			sp-=16*plScrLineBytes-8;
357 		} else
358 			sp+=8;
359 }
360