-
Notifications
You must be signed in to change notification settings - Fork 1
/
MUConvert.c
214 lines (192 loc) · 4.53 KB
/
MUConvert.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*
* MUConvert for Yuzo Koshiro's MUCOM88
* 2019 Artemio Urbina
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_LEN 1024
#define UNDEFINED 0
#define PC88 1
#define MUC 2
void PC88writeline(char *buffer, int len, int comment, int *line, FILE *out, int skipheader)
{
if(skipheader)
{
if(!strncmp(buffer, "#mucom88", 8))
return;
if(!strncmp(buffer, "#title", 6))
return;
if(!strncmp(buffer, "#composer", 9))
return;
if(!strncmp(buffer, "#author", 7))
return;
if(!strncmp(buffer, "#voice", 6))
return;
if(!strncmp(buffer, "#pcm", 4))
return;
if(!strncmp(buffer, "#date", 5))
return;
if(!strncmp(buffer, "#comment", 8))
return;
if(*line == 10 && !len)
return;
}
fprintf(out, "%d '", *line);
fwrite(buffer, sizeof(char), len, out);
fprintf(out, "\r\n");
*line += 10;
}
void MUCwriteline(char *buffer, int len, FILE *out)
{
fwrite(buffer, sizeof(char), len, out);
fprintf(out, "\r\n");
}
int MUCtoPC88(FILE *file, FILE *out, int removecomments, int skipheader)
{
char buffer[BUFFER_LEN];
int read = 0, comment = 0, line = 10,
pos = 0, lastlen = 0;
while (!feof(file))
{
read = fgetc(file);
if(read != EOF)
{
if(read == '\t')
read = ' ';
switch(read)
{
case 0x0D: // Ignore
break;
case 0x0A: // Enter
if(pos || !pos && lastlen) // eat up multipe empty lines
PC88writeline(buffer, pos, comment, &line, out, skipheader);
lastlen = pos;
pos = 0;
comment = 0;
break;
case ';': //commented line, ignore
if(removecomments)
comment = 1;
break;
default:
if(!comment)
{
if(pos < BUFFER_LEN)
buffer[pos++] = read;
else
{
PC88writeline(buffer, pos, comment, &line, out, skipheader);
pos = 0;
buffer[pos++] = read;
}
}
break;
}
}
}
printf("Done. Use dskdrv02a with M88 to insert basic file into D88 disk image");
return 1;
}
int PC88toMUC(FILE *file, FILE *out)
{
char buffer[BUFFER_LEN];
int read = 0, linenum = 0, pos = 0, header = 0;
fprintf(out, "#mucom88 1.x\r\n#title MUC file\r\n#composer Unknown\r\n");
fprintf(out, "#author Unknown\r\n#voice EDITME\r\n#pcm EDITME\r\n");
fprintf(out, "#comment Exported from PC8801 with MUConverter\r\n\r\n");
while (!feof(file))
{
read = fgetc(file);
if(read != EOF)
{
switch(read)
{
case 0x0D: // Ignore
break;
case 0x0A: // Enter
if(!header)
MUCwriteline(buffer, pos, out);
header = 0;
pos = 0;
break;
case '\'': // reset counter and copy data until enter
linenum = atol(buffer);
if(!linenum)
{
printf("Invalid PC-8801 BASIC format, aborting\n");
printf("Line data: %s\n", buffer);
return 0;
}
if(linenum == 1)
header = 1;
linenum = 0;
pos = 0;
break;
default:
if(pos < BUFFER_LEN)
buffer[pos++] = read;
else
{
printf("Invalid format or buffer length exceeded\nAborting");
return 0;
}
break;
}
}
}
printf("Done. Don\'t forget to edit the #voice and #pcm lines to the file\n");
return 1;
}
void ShowUsage()
{
printf("Usage:\n\tMUConvert -pc88 <source> <target> [-withcomments] [-withheader]\n");
printf("\tMUConvert -muc <source> <target>\n");
printf("\t-pc88: Adds BASIC line numbers, removes Tabs and Comments by default\n");
printf("\t-muc: Removes BASIC line numbers and file header from exported BASIC file\n");
printf("\t-withcomments: In PC88 mode leaves all comments intact\n");
printf("\t-withheader: In PC88 mode leaves header intact\n");
}
int main(int argc, char **argv)
{
FILE *file, *out;
int type = UNDEFINED, removecomments = 1, skipheader = 1;
printf("MUC Windows <-> PC-88 MUCOM88 converter\n");
printf("\tArtemio Urbina 2019 under GPL\n\tThanks to Yuzo Koshiro\n");
if(argc >= 4)
{
if(!strcmp(argv[1], "-muc"))
type = MUC;
if(!strcmp(argv[1], "-pc88"))
type = PC88;
}
if(argc >= 5 && !strcmp(argv[4], "-withcomments"))
removecomments = 0;
if(argc == 6 && !strcmp(argv[5], "-withheader"))
skipheader = 0;
if(type == UNDEFINED || argc < 4)
{
ShowUsage();
return 0;
}
file = fopen(argv[2], "rb");
if(!file)
{
printf("Could not open file %s\n", argv[2]);
return 0;
}
out = fopen(argv[3], "wb");
if(!out)
{
printf("Could not open file %s for writing\n", argv[3]);
return 0;
}
printf("Converting %s to %s\n", argv[2], argv[3]);
if(type == PC88)
MUCtoPC88(file, out, removecomments, skipheader);
if(type == MUC)
PC88toMUC(file, out);
fclose(file);
fclose(out);
return 0;
}