1 /*
2 psftools: Manipulate console fonts in the .PSF format
3 Copyright (C) 2005-6 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 "config.h"
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <ctype.h>
24 #include "psflib.h"
25
dump_mapping(PSF_MAPPING * m)26 psf_errno_t dump_mapping(PSF_MAPPING *m)
27 {
28 FILE *fp;
29 char *filename, *tmp;
30 int n, p;
31 long total;
32 unsigned char header[128];
33 unsigned char data[4];
34
35 memset(header, 0, sizeof header);
36 strcpy((char *)header, "PSFTOOLS CODEPAGE MAP\r\n\032");
37
38 filename = malloc(5 + strlen(m->psfm_name));
39 if (!filename) return PSF_E_NOMEM;
40 strcpy(filename, m->psfm_name);
41 tmp = filename + strlen(filename) - 1;
42 /* Chop off any filename extension, but leave the path untouched */
43 while (tmp > filename)
44 {
45 if (*tmp == '/' || *tmp == '\\' || *tmp == ':') break;
46 if (*tmp == '.')
47 {
48 *tmp = 0;
49 break;
50 }
51 --tmp;
52 }
53 strcat(filename, ".cp2");
54 fprintf(stderr, "Dumping %s as %s\n", m->psfm_name,
55 filename);
56
57 fp = fopen(filename, "wb");
58 if (!fp)
59 {
60 perror(filename);
61 return PSF_E_ERRNO;
62 }
63 total = 0;
64 for (n = 0; n < 256; n++)
65 {
66 for (p = 0; m->psfm_tokens[n][p] != 0xFFFF; p++);
67 total += (p + 1);
68 }
69 header[0x40] = (total) & 0xFF;
70 header[0x41] = (total >> 8) & 0xFF;
71 header[0x42] = (total >> 16) & 0xFF;
72 header[0x43] = (total >> 24) & 0xFF;
73 fwrite(header, 1, sizeof(header), fp);
74 for (n = 0; n < 256; n++)
75 {
76 for (p = 0; m->psfm_tokens[n][p] != 0xFFFF; p++)
77 {
78 data[0] = (m->psfm_tokens[n][p]) & 0xFF;
79 data[1] = (m->psfm_tokens[n][p] >> 8) & 0xFF;
80 data[2] = (m->psfm_tokens[n][p] >> 16) & 0xFF;
81 data[3] = (m->psfm_tokens[n][p] >> 24) & 0xFF;
82 fwrite(data, 1, sizeof(data), fp);
83 }
84 data[0] = data[1] = 0xFF;
85 data[2] = data[3] = 0;
86 fwrite(data, 1, sizeof(data),fp);
87 }
88 fclose(fp);
89 return PSF_E_OK;
90 }
91
92 #ifdef __PACIFIC__
93 #define AV0 "cp2page"
94 #else
95 #define AV0 argv[0]
96 #endif
97
syntax(char * av0)98 void syntax(char *av0)
99 {
100 fprintf(stderr, "Syntax: %s codepage { codepage codepage ... }\n",
101 av0);
102 fprintf(stderr, "\nWrites the specified codepage(s) as .CP2 file(s).\n"
103 "Built-in pages get saved in the current directory.\n"
104 "Pages loaded from files get written in the same "
105 "directory as those files.\n");
106 }
107
main(int argc,char ** argv)108 int main(int argc, char **argv)
109 {
110 PSF_MAPPING *m;
111 psf_errno_t err;
112 int n;
113
114 if (argc < 2)
115 {
116 syntax(AV0);
117 return 0;
118 }
119 for (n = 1; n < argc; n++)
120 {
121 if (!strcmp(argv[n], "--help"))
122 {
123 syntax(AV0);
124 return 0;
125 }
126 m = psf_find_mapping(argv[n]);
127 if (!m)
128 {
129 fprintf(stderr, "Cannot find codepage %s\n",
130 argv[n]);
131 return 1;
132 }
133 err = dump_mapping(m);
134 if (err)
135 {
136 fprintf(stderr, "%s: %s", argv[n],
137 psf_error_string(err));
138 return 1;
139 }
140 }
141 return 0;
142 }
143
144