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