1 /*
2     psftools: Manipulate console fonts in the .PSF format
3     Copyright (C) 2000, 2005  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 
20 /* Convert a PSF file to a C include file. Used while building zx2psf. */
21 
22 #include "cnvshell.h"
23 #include "psflib.h"
24 
25 char *cnv_progname = "PSF2INC";
26 
27 static char helpbuf[2000];
28 static int v1 = 0, v2 = 0, fasm = 0;
29 
cnv_set_option(int ddash,char * variable,char * value)30 char *cnv_set_option(int ddash, char *variable, char *value)
31 {
32     if (!stricmp(variable, "psf1"))   { v1 = 1; return NULL; }
33     if (!stricmp(variable, "psf2"))   { v2 = 1; return NULL; }
34     if (!stricmp(variable, "asm"))    { fasm = 1; return NULL; }
35     if (strlen(variable) > 2000) variable[2000] = 0;
36     sprintf(helpbuf, "Unknown option: %s\n", variable);
37     return helpbuf;
38 }
39 
40 /* Return help string */
cnv_help(void)41 char *cnv_help(void)
42     {
43     sprintf(helpbuf, "Syntax: %s psffile incfile { options }\n\n", cnv_progname);
44     strcat (helpbuf, "Options: \n"
45                      "    --psf1         Force PSF1 format\n"
46                      "    --psf2         Force PSF2 format\n"
47 		     "    --asm          Output in RMAC/RASM86 format\n");
48 
49     return helpbuf;
50     }
51 
52 static psf_dword filepos;
53 
54 static int startline;
55 
put_comment(PSFIO * io,char * s)56 static void put_comment(PSFIO *io, char *s)
57 {
58 	if (fasm) fprintf(io->data.fp, "  ; %s\n", s);
59 	else	  fprintf(io->data.fp,"  /* %s */\n   ", s);
60 	startline = 1;
61 }
62 
put_newline(PSFIO * io)63 static void put_newline(PSFIO *io)
64 {
65 	if (fasm) 	fprintf(io->data.fp, "\n");
66 	else		fprintf(io->data.fp, "\n   ");
67 	startline = 1;
68 }
69 
70 
write_printf(PSFIO * io,psf_byte b)71 int write_printf(PSFIO *io, psf_byte b)
72 {
73 	static psf_dword ch, x, cb;
74 	int ct = 0;
75 	static psf_byte pch;
76 
77 	if (!filepos)
78 	{
79 		put_newline(io);
80 		ch = 0;
81 		x = 0;
82 		cb = 0;
83 	}
84 	if (fasm)
85 	{
86 		if (startline)
87 		{
88 			fprintf(io->data.fp, "\tdb\t");
89 			startline = 0;
90 		}
91 		else
92 		{
93 			fprintf(io->data.fp, ", ");
94 		}
95 		fprintf(io->data.fp, "0%02xh", b);
96 	}
97 	else	  fprintf(io->data.fp, "0x%02x, ", b);
98 	if (io->psf->psf_magic == PSF1_MAGIC) switch(filepos)
99 	{
100 		case 1: put_comment(io, "Magic"); x = 0; cb = 0; ct = 1; break;
101 		case 2: put_comment(io, "Type");  x = 0; cb = 0; ct = 1; break;
102 		case 3: put_comment(io, "Char size"); x = 0; cb = 0; ct = 1; break;
103 	}
104 	if (io->psf->psf_magic == PSF_MAGIC) switch(filepos)
105 	{
106 		case  3: put_comment(io, "Magic");        x = 0; cb = 0; ct = 1; break;
107 		case  7: put_comment(io, "Version");      x = 0; cb = 0; ct = 1; break;
108 		case 11: put_comment(io, "Header size");  x = 0; cb = 0; ct = 1; break;
109 		case 15: put_comment(io, "Flags");        x = 0; cb = 0; ct = 1; break;
110 		case 19: put_comment(io, "No. of chars"); x = 0; cb = 0; ct = 1; break;
111 		case 23: put_comment(io,"Char length");  x = 0; cb = 0; ct = 1; break;
112 		case 27: put_comment(io,"Char width");   x = 0; cb = 0; ct = 1; break;
113 		case 31: put_comment(io, "Char height");  x = 0; cb = 0; ct = 1; break;
114 	}
115 	++filepos;
116 	if (ct) { pch = b; return PSF_E_OK; }
117 	if (ch >= io->psf->psf_length)	/* Unicode dir */
118 	{
119 		if (io->psf->psf_magic == PSF_MAGIC && b == 0xFF)
120 		{
121 			put_newline(io);
122 			x = 0;
123 		}
124 		if (io->psf->psf_magic == PSF1_MAGIC && b == 0xFF && pch == 0xFF)
125 		{
126 			put_newline(io);
127 			x = 0;
128 		}
129 	}
130 
131 	cb++;
132 	if (cb == io->psf->psf_charlen && ch < io->psf->psf_length)
133 	{
134 		char buf[30];
135 		sprintf(buf, "%ld", ch++);
136 		put_comment(io, buf);
137 		cb = x = 0;
138 	}
139 	else x++;
140 	if (x == 8)
141 	{
142 		put_newline(io);
143 		x = 0;
144 	}
145 
146 	pch = b;
147 	return PSF_E_OK;;
148 }
149 
150 
151 
152 
cnv_execute(FILE * infile,FILE * outfile)153 char *cnv_execute(FILE *infile, FILE *outfile)
154 {
155 	int rv;
156 	PSF_FILE psf;
157 	PSFIO psfio;
158 	char *s = NULL;
159 
160 	filepos = 0;
161 	psf_file_new(&psf);
162 	rv = psf_file_read(&psf, infile);
163 
164 	if (rv != PSF_E_OK) return psf_error_string(rv);
165 
166 	psfio.psf = &psf;
167 	psfio.readfunc  = NULL;
168 	psfio.writefunc = write_printf;
169 	psfio.data.fp = outfile;
170 
171 	if (v1) psf_force_v1(&psf);
172 	if (v2) psf_force_v2(&psf);
173 
174 	if ((rv = psf_write(&psfio))) s = psf_error_string(rv);
175 	else fprintf(outfile, "\n");
176 
177 	psf_file_delete(&psf);
178 	return s;
179 }
180 
181