1 /*
2     psftools: Manipulate console fonts in the .PSF format
3     Copyright (C) 2005, 2008  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 BBC Micro-format soft font
24  * (on an Arc, this would be filetype FF7) */
25 
26 #define MAX_H 8	/* Max font height */
27 
28 char *cnv_progname = "PSF2BBC";
29 
30 static char helpbuf[2048];
31 static int fx = 0;
32 static int first = 32;
33 static int last = 255;
34 static psf_byte charbuf[MAX_H];
35 
cnv_set_option(int ddash,char * variable,char * value)36 char *cnv_set_option(int ddash, char *variable, char *value)
37 {
38 /*
39 	if (!stricmp(variable, "dest"))
40 	{
41 		dest = atoi(value);
42 		if (dest < 32 || dest > 255)
43 			return "--dest: Character cell must be 32-255\n";
44 		return NULL;
45 	} */
46 	if (!stricmp(variable, "first")) { first = atoi(value); return NULL; }
47 	if (!stricmp(variable, "last"))  { last  = atoi(value); return NULL; }
48 	if (!stricmp(variable, "fx"))    { fx = 1; return NULL; }
49 	if (!stricmp(variable, "fx20"))  { fx = 1; return NULL; }
50 
51 	sprintf(helpbuf, "Unknown option: %s", variable);
52 	return helpbuf;
53 }
54 
cnv_help(void)55 char *cnv_help(void)
56     {
57     sprintf(helpbuf, "Syntax: %s { options } psf_file softfont_file\n\n"
58 		     "Options:\n"
59 		     "   --dest=x   The font will start at character cell x (32-255)\n"
60 		     "   --first=x  First character to go into the soft font\n"
61 		     "   --last=x   Last character to go into the soft font\n"
62 		     "   --fx       Generate *FX20 commands for the original\n"
63 		     "              BBC Micro to expand its character RAM\n"
64 		    ,cnv_progname);
65     return helpbuf;
66     }
67 
68 
69 
cnv_execute(FILE * fpin,FILE * fpout)70 char *cnv_execute(FILE *fpin, FILE *fpout)
71 {
72 	int rv;
73 	PSF_FILE psf;
74 	psf_dword ch;
75 	psf_dword y, wb;
76 
77 	psf_file_new(&psf);
78 	rv = psf_file_read(&psf, fpin);
79 	if (rv != PSF_E_OK) return psf_error_string(rv);
80 
81 	if (psf.psf_width > 8)
82 	{
83 		fprintf(stderr, "Warning: Input file is wider than 8 pixels. Truncating at 8.\n");
84 	}
85 	if (psf.psf_height > MAX_H)
86 	{
87 		fprintf(stderr, "Warning: Input file is higher than %d pixels. Truncating.\n", MAX_H);
88 	}
89 	if ((psf.psf_length - 1) < first) first = psf.psf_length - 1;
90 	if ((psf.psf_length - 1) < last)  last  = psf.psf_length - 1;
91 
92 	if (fx) for (y = 1; y <= 6; y++)
93 	{
94 		fprintf(fpout, "*FX20 %ld\r", y);
95 	}
96 	/* wb = number of bytes per line */
97 	wb = psf.psf_charlen / psf.psf_height;
98 	for (ch = first; ch <= last; ch++)
99 	{
100 		if (ch < 32)
101 		{
102 			ch = 31;
103 			fprintf(stderr, "Warning: Characters numbered below 32 will be ignored.\n");
104 			continue;
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(0x17, fpout);		// VDU23
116 		fputc(ch,   fpout);		// character
117 		for (y = 0; y < 8; y++)
118 		{
119 			fprintf(fpout, "%c", charbuf[y]);	// Char shape
120 		}
121 	}
122 
123 	psf_file_delete(&psf);
124 	return 0;
125 }
126 
127