1 /*
2     psftools: Manipulate console fonts in the .PSF format
3     Copyright (C) 2005, 2007  John Elliott
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 #include <stdio.h>
20 #include "cnvshell.h"
21 #include "psflib.h"
22 
23 /* Convert a PSF file to a Wyse-format soft font */
24 
25 #define MAX_H 32	/* Max font height */
26 
27 char *cnv_progname = "PSF2WYSE";
28 
29 static char helpbuf[2048];
30 static int bank = 0;
31 static int dest = 0;
32 static int first = 0;
33 static int height = 16;
34 static int nulls = 8;
35 static int last = 511;
36 static psf_byte charbuf[MAX_H];
37 
cnv_set_option(int ddash,char * variable,char * value)38 char *cnv_set_option(int ddash, char *variable, char *value)
39 {
40 	if (!stricmp(variable, "bank"))
41 	{
42 		bank = atoi(value);
43 		if (bank < 0 || bank > 3) return "--bank: Bank must be 0 to 3";
44 		return NULL;
45 	}
46 	if (!stricmp(variable, "dest"))
47 	{
48 		dest = atoi(value);
49 		if (dest < 0 || dest > 127)
50 			return "--dest: Character cell must be 0-127\n";
51 		return NULL;
52 	}
53 	if (!stricmp(variable, "first")) { first = atoi(value); return NULL; }
54 	if (!stricmp(variable, "last"))  { last  = atoi(value); return NULL; }
55 	if (!stricmp(variable, "height")){ height = atoi(value); return NULL; }
56 	if (!stricmp(variable, "nulls")) { nulls = atoi(value); return NULL; }
57 
58 	sprintf(helpbuf, "Unknown option: %s", variable);
59 	return helpbuf;
60 }
61 
cnv_help(void)62 char *cnv_help(void)
63     {
64     sprintf(helpbuf, "Syntax: %s { options } psf_file softfont_file\n\n"
65 		     "Options:\n"
66 		     "   --bank=x   The font will use font bank x (0-3)\n"
67 		     "              (eg: bank 0 for 25-line modes, bank 2 for 43-line modes)\n"
68 		     "   --dest=x   The font will start at character cell x (0-127)\n"
69 		     "   --height=x Height of defined characters (default 16)\n"
70 		     "   --first=x  First character to go into the soft font\n"
71 		     "   --last=x   Last character to go into the soft font\n"
72 		     "   --nulls=x  Send x NUL characters after each definition\n"
73 		    ,cnv_progname);
74     return helpbuf;
75     }
76 
77 
78 
cnv_execute(FILE * fpin,FILE * fpout)79 char *cnv_execute(FILE *fpin, FILE *fpout)
80 {
81 	int rv;
82 	PSF_FILE psf;
83 	psf_dword ch;
84 	psf_dword y, wb;
85 
86 	psf_file_new(&psf);
87 	rv = psf_file_read(&psf, fpin);
88 	if (rv != PSF_E_OK) return psf_error_string(rv);
89 
90 	if (psf.psf_width > 8)
91 	{
92 		fprintf(stderr, "Warning: Input file is wider than 8 pixels. Truncating at 8.\n");
93 	}
94 	if (height > MAX_H)
95 	{
96 		fprintf(stderr, "Warning: Height cannot exceed %d. Truncating.\n", MAX_H);
97 		height = MAX_H;
98 	}
99 	if ((psf.psf_length - 1) < first) first = psf.psf_length - 1;
100 	if ((psf.psf_length - 1) < last)  last  = psf.psf_length - 1;
101 
102 	/* wb = number of bytes per line */
103 	wb = psf.psf_charlen / psf.psf_height;
104 	for (ch = first; ch <= last; ch++)
105 	{
106 		memset(charbuf, 0, sizeof(charbuf));
107 
108 		/* Populate character buffer */
109 		for (y = 0; y < psf.psf_height; y++)
110 		{
111 			if (y >= MAX_H) break;
112 			charbuf[y] = psf.psf_data[ch * psf.psf_charlen +
113 			       			  y * wb];
114 		}
115 		fputc(0x1B, fpout);		// ESC
116 		fputc('c',  fpout);		// c
117 		fputc('A',  fpout);		// A  : Redefine
118 		fputc(bank + '0', fpout);	// Bank
119 		fprintf(fpout, "%02x", dest);	// Dest cell
120 		for (y = 0; y < height; y++)
121 		{
122 			fprintf(fpout, "%02x", charbuf[y]);	// Char shape
123 		}
124 		fputc(0x19, fpout);		// End of char definition
125 		for (y = 0; y < nulls; y++)
126 		{
127 			fputc(0, fpout);
128 		}
129 		++dest;
130 		if (dest == 0x80)
131 		{
132 			dest = 0;
133 			++bank;
134 			if (bank > 3) break;
135 		}
136 	}
137 
138 	psf_file_delete(&psf);
139 	return 0;
140 }
141 
142