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