/[projet1]/public/pc/tools/osdk/main/FloppyBuilder/FloppyBuilder.cpp
Defence Force logotype

Contents of /public/pc/tools/osdk/main/FloppyBuilder/FloppyBuilder.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1329 - (show annotations)
Sat Oct 24 20:40:51 2015 UTC (3 years, 10 months ago) by dbug
File size: 13311 byte(s)
FloppyBuilder 0.18
- Added a 'ReserveSectors' command that can be used to leave room on the disk for save games or stuff like that.
1
2 #include <cstdlib>
3 #include <stdio.h>
4 #include <string.h>
5 #include <sstream>
6 #include <iostream>
7 #include <vector>
8
9 #include "infos.h"
10 #include "common.h"
11 #include "Floppy.h"
12
13
14 // while (std::getline(iss,item,' '))
15 bool GetNextToken(std::string& returnedToken,std::string& restOfLine,int lineNumber)
16 {
17 returnedToken.clear();
18
19 const char* startOfLine =restOfLine.c_str();
20 const char* currentPosition=startOfLine;
21 char car;
22
23 // First skip all the white space stuff
24 while ( (car=*currentPosition) && ( (car==' ') || (car=='\t') ) )
25 {
26 ++currentPosition;
27 }
28
29 // Then depending of the character we have, we need a terminator token
30 if (car)
31 {
32 char match =0;
33
34 if (car=='"')
35 {
36 match='"';
37 }
38 else
39 if (car=='{')
40 {
41 match='}';
42 }
43 else
44 if (car=='[')
45 {
46 match =']';
47 }
48
49 if (match)
50 {
51 // Push the starting character
52 returnedToken.push_back(car);
53 ++currentPosition;
54 }
55
56 while ( (car=*currentPosition) && ( (match && (car!=match)) || ( (!match) && ((car!=' ') && (car!='\t')) ) ) )
57 {
58 returnedToken.push_back(car);
59 ++currentPosition;
60 }
61
62 if (match && (car==match))
63 {
64 // Including the matching character
65 returnedToken.push_back(car);
66 ++currentPosition;
67 car=*currentPosition;
68 }
69
70 if (car)
71 {
72 // We have reach the end of the token, just make sure there's a white space behind
73 if ((car==' ') || (car=='\t'))
74 {
75 restOfLine=currentPosition;
76 }
77 else
78 {
79 // Parse error
80 ShowError("Parse error line '%d'\n",lineNumber);
81 }
82 }
83 else
84 {
85 // End of Line
86 restOfLine.clear();
87 }
88 return true;
89 }
90 return false;
91 }
92
93 int main(int argc, char *argv[])
94 {
95 //
96 // Some initialization for the common library
97 //
98 SetApplicationParameters(
99 "FloppyBuilder",
100 TOOL_VERSION_MAJOR,
101 TOOL_VERSION_MINOR,
102 "{ApplicationName} - Version {ApplicationVersion} - This program is a part of the OSDK\r\n"
103 "\r\n"
104 "Author:\r\n"
105 " (c) 2002 Debrune Jerome for the initial version \r\n"
106 " (c) 2015 Pointier Mickael for the subsequent changes \r\n"
107 "\r\n"
108 "Purpose:\r\n"
109 " Generating bootable floppies for the Oric computer.\r\n"
110 "\r\n"
111 "Usage:\r\n"
112 " {ApplicationName} <init|build|extract> <description file path>\r\n"
113 "\r\n"
114 );
115
116 // makedisk filetobuild.txt default.dsk ..\build\%OSDKDISK%
117
118 long param=1;
119
120 if (argc>1)
121 {
122 for (;;)
123 {
124 long nb_arg=argc;
125 //const char *ptr_arg=argv[param];
126
127 if (nb_arg==argc) break;
128 }
129 }
130
131
132 if (argc!=3)
133 {
134 ShowError(nullptr);
135 }
136
137 Floppy floppy;
138
139 bool extract=false;
140 if (!strcmp(argv[param],"init"))
141 {
142 floppy.AllowMissingFiles(true);
143 }
144 else
145 if (!strcmp(argv[param],"extract"))
146 {
147 floppy.AllowMissingFiles(true);
148 extract=true;
149 }
150 else
151 if (!strcmp(argv[param],"build"))
152 {
153 floppy.AllowMissingFiles(false);
154 }
155 else
156 {
157 ShowError("The first parameter should be either 'init' or 'build'.");
158 }
159 param++;
160
161
162 //
163 // Open the description file
164 //
165 const char* description_name(argv[param]);
166 std::vector<std::string> script;
167 if (!LoadText(description_name,script))
168 {
169 ShowError("Can't load script file '%s'\n",description_name);
170 }
171
172
173 std::string outputLayoutFileName;
174 std::string targetFloppyDiskName;
175
176 int lineNumber=0;
177 for (auto it(script.begin());it!=script.end();++it)
178 {
179 ++lineNumber;
180
181 std::string currentLine(*it);
182
183 std::size_t found = currentLine.find(";");
184 if (found!=std::string::npos)
185 {
186 // Comments, just skip them
187 currentLine=currentLine.substr(0,found);
188 }
189
190 std::istringstream iss(currentLine);
191
192 std::map<std::string,std::string> metadata;
193 std::string item;
194 std::vector<std::string> tokens;
195 //while (std::getline(iss,item,' '))
196 while (GetNextToken(item,currentLine,lineNumber))
197 {
198 // Remove eventual superfluous spaces and tabs
199 item=StringTrim(item);
200 if (!item.empty())
201 {
202 if ( ((*item.begin())=='[') && ((*item.rbegin())==']') )
203 {
204 // Let's say it's metadata
205 std::string metaItem=StringTrim(item,"[]");
206 std::size_t found = metaItem.find(":");
207 if (found!=std::string::npos)
208 {
209 // Comments, just skip them
210 std::string key =metaItem.substr(0,found);
211 std::string value=metaItem.substr(found+1);
212 metadata[key]=value;
213 }
214 else
215 {
216 ShowError("Syntax error line (%d), found invalid '%s' metadata format, should be '[key:value]'\n",lineNumber,item.c_str());
217 }
218 }
219 else
220 {
221 // Let's say it's an actual parameter
222 item=StringTrim(item,"\"");
223 tokens.push_back(item);
224 }
225 }
226 }
227
228 if (!tokens.empty())
229 {
230 if (tokens[0]=="LoadDiskTemplate")
231 {
232 if (tokens.size()==2)
233 {
234 const std::string& templateFisk(tokens[1]);
235 if (!floppy.LoadDisk(templateFisk.c_str()))
236 {
237 ShowError("Can't load '%s'\n",templateFisk.c_str());
238 }
239
240 }
241 else
242 {
243 ShowError("Syntax error line (%d), syntax is 'LoadDiskTemplate FilePath' \n",lineNumber);
244 }
245 }
246 else
247 if (tokens[0]=="DefineDisk")
248 {
249 if (tokens.size()==4)
250 {
251 int numberOfSides =std::atoi(tokens[1].c_str());
252 int numberOfTracks =std::atoi(tokens[2].c_str());
253 int numberOfSectors =std::atoi(tokens[3].c_str());
254
255 if ( numberOfSides!=2 )
256 {
257 ShowError("Syntax error line (%d), numberOfSides has to be 2 (so far)\n",lineNumber);
258 }
259
260 /*
261 if ( numberOfTracks!=42 )
262 {
263 ShowError("Syntax error line (%d), numberOfTracks has to be 42 (so far)\n",lineNumber);
264 }
265 */
266
267 if ( numberOfSectors!=17 )
268 {
269 ShowError("Syntax error line (%d), numberOfSectors has to be 17 (so far)\n",lineNumber);
270 }
271
272 if (!floppy.CreateDisk(numberOfSides,numberOfTracks,numberOfSectors))
273 {
274 ShowError("Can't create the requested disk format\n");
275 }
276
277 }
278 else
279 {
280 ShowError("Syntax error line (%d), syntax is 'DefineDisk numberOfSides numberOfTracks numberOfSectors' \n",lineNumber);
281 }
282 }
283 else
284 if (tokens[0]=="OutputLayoutFile")
285 {
286 if (tokens.size()==2)
287 {
288 outputLayoutFileName=tokens[1];
289 }
290 else
291 {
292 ShowError("Syntax error line (%d), syntax is 'OutputLayoutFile FilePath' \n",lineNumber);
293 }
294 }
295 else
296 if (tokens[0]=="OutputFloppyFile")
297 {
298 if (tokens.size()==2)
299 {
300 targetFloppyDiskName=tokens[1];
301 }
302 else
303 {
304 ShowError("Syntax error line (%d), syntax is 'targetFloppyDiskName FilePath' \n",lineNumber);
305 }
306 }
307 else
308 if (tokens[0]=="SetPosition")
309 {
310 if (tokens.size()==3)
311 {
312 int currentTrack =std::atoi(tokens[1].c_str());
313 if ( (currentTrack<0) || (currentTrack>41) )
314 {
315 ShowError("Syntax error line (%d), TrackNumber has to be between 0 and 41' \n",lineNumber);
316 }
317 int currentSector=std::atoi(tokens[2].c_str());
318 if ( (currentSector<0) || (currentSector>41) )
319 {
320 ShowError("Syntax error line (%d), SectorNumber has to be between 1 and 17' \n",lineNumber);
321 }
322 floppy.SetPosition(currentTrack,currentSector);
323 }
324 else
325 {
326 ShowError("Syntax error line (%d), syntax is 'SetPosition TrackNumber SectorNumber' \n",lineNumber);
327 }
328 }
329 else
330 if (tokens[0]=="WriteSector")
331 {
332 if (tokens.size()==2)
333 {
334 std::string fileName=tokens[1];
335 if (!floppy.WriteSector(fileName.c_str()))
336 {
337 ShowError("Error line (%d), could not write file '%s' to disk. Make sure you have a valid floppy format declared. \n",lineNumber,fileName.c_str());
338 }
339 }
340 else
341 {
342 ShowError("Syntax error line (%d), syntax is 'WriteSector FilePath' \n",lineNumber);
343 }
344 }
345 else
346 if (tokens[0]=="AddFile")
347 {
348 if (tokens.size()==3)
349 {
350 std::string fileName=tokens[1];
351 int loadAddress=ConvertAdress(tokens[2].c_str());
352 if (!floppy.WriteFile(fileName.c_str(),loadAddress,false,metadata))
353 {
354 ShowError("Error line (%d), could not write file '%s' to disk. Make sure you have a valid floppy format declared. \n",lineNumber,fileName.c_str());
355 }
356 }
357 else
358 {
359 ShowError("Syntax error line (%d), syntax is 'AddFile FilePath LoadAddress' \n",lineNumber);
360 }
361 }
362 else
363 if (tokens[0]=="AddTapFile")
364 {
365 if (tokens.size()==2)
366 {
367 std::string fileName=tokens[1];
368 if (!floppy.WriteFile(fileName.c_str(),-1,true,metadata))
369 {
370 ShowError("Error line (%d), could not write file '%s' to disk. Make sure you have a valid floppy format declared. \n",lineNumber,fileName.c_str());
371 }
372 }
373 else
374 {
375 ShowError("Syntax error line (%d), syntax is 'AddTapFile FilePath' \n",lineNumber);
376 }
377 }
378 else
379 if (tokens[0]=="ReserveSectors")
380 {
381 if ( (tokens.size()==2) || (tokens.size()==3) )
382 {
383 int sectorCount=ConvertAdress(tokens[1].c_str());
384 int fillValue=0;
385 if (tokens.size()==3)
386 {
387 fillValue=ConvertAdress(tokens[2].c_str());
388 }
389 if (!floppy.ReserveSectors(sectorCount,fillValue,metadata))
390 {
391 ShowError("Error line (%d), could not reserve %u sectors on the disk. Make sure you have a valid floppy format declared. \n",lineNumber,sectorCount);
392 }
393 }
394 else
395 {
396 ShowError("Syntax error line (%d), syntax is 'ReserveSectors SectorCount [FillValue]' \n",lineNumber);
397 }
398 }
399 else
400 if (tokens[0]=="SaveFile")
401 {
402 // ; SaveFile "File_0.bin" $80 $01 $47 ; Name Track Sector Lenght adress
403 if (tokens.size()==5)
404 {
405 std::string fileName=tokens[1];
406 int trackNumber =ConvertAdress(tokens[2].c_str());
407 int sectorNumber=ConvertAdress(tokens[3].c_str());
408 int sectorCount =ConvertAdress(tokens[4].c_str());
409 if (!floppy.ExtractFile(fileName.c_str(),trackNumber,sectorNumber,sectorCount))
410 {
411 ShowError("Error line (%d), could not extract file '%s' from disk. Make sure you have a valid floppy format declared and some available disk space. \n",lineNumber,fileName.c_str());
412 }
413 }
414 else
415 {
416 ShowError("Syntax error line (%d), syntax is 'ExtractFile FilePath TrackNumber SectorNumber SectorCount' \n",lineNumber);
417 }
418 }
419 else
420 if (tokens[0]=="AddDefine")
421 {
422 if (tokens.size()==3)
423 {
424 floppy.AddDefine(tokens[1],tokens[2]);
425 }
426 else
427 {
428 ShowError("Syntax error line (%d), syntax is 'AddDefine DefineName DefineValue' \n",lineNumber);
429 }
430 }
431 else
432 if (tokens[0]=="SetCompressionMode")
433 {
434 if (tokens.size()==2)
435 {
436 if (tokens[1]=="None")
437 {
438 floppy.SetCompressionMode(e_CompressionNone);
439 }
440 else
441 if (tokens[1]=="FilePack")
442 {
443 floppy.SetCompressionMode(e_CompressionFilepack);
444 }
445 else
446 {
447 ShowError("Syntax error line (%d), '%s' is not a valid compression mode, it should be either 'None' or 'FilePack' \n",lineNumber,tokens[1].c_str());
448 }
449 }
450 else
451 {
452 ShowError("Syntax error line (%d), syntax is 'SetCompressionMode [None|FilePack]' \n",lineNumber);
453 }
454 }
455 else
456 {
457 ShowError("Syntax error line (%d), unknown keyword '%s' \n",lineNumber,tokens[0].c_str());
458 }
459 }
460 }
461
462
463 if (!extract)
464 {
465 // We write the resulting files only in 'init' or 'build' mode
466 if (!floppy.SaveDescription(outputLayoutFileName.c_str()))
467 {
468 ShowError("Failed saving description '%s'\n",outputLayoutFileName.c_str());
469 }
470
471 if (!floppy.SaveDisk(targetFloppyDiskName.c_str()))
472 {
473 ShowError("Failed saving disk '%s'\n",targetFloppyDiskName.c_str());
474 }
475 else
476 {
477 printf("Successfully created '%s'\n",targetFloppyDiskName.c_str());
478 }
479 }
480 }

  ViewVC Help
Powered by ViewVC 1.1.26