1 /*****************************************************************************/
5 /* Main program of the sp65 sprite and bitmap utility */
9 /* (C) 2012, Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
56 /*****************************************************************************/
58 /*****************************************************************************/
62 /* Bitmap first read */
65 /* Bitmap working copy */
68 /* Output data from convertion */
73 /*****************************************************************************/
75 /*****************************************************************************/
79 static void Usage (void)
80 /* Print usage information and exit */
83 "Usage: %s [options] file [options] [file]\n"
85 " -V\t\t\t\tPrint the version number and exit\n"
86 " -c fmt[,attrlist]\t\tConvert into target format\n"
87 " -h\t\t\t\tHelp (this text)\n"
88 " -lc\t\t\t\tList all possible conversions\n"
89 " -r file[,attrlist]\t\tRead an input file\n"
90 " -v\t\t\t\tIncrease verbosity\n"
91 " -w file[,attrlist]\t\tWrite the output to a file\n"
94 " --convert-to fmt[,attrlist]\tConvert into target format\n"
95 " --help\t\t\tHelp (this text)\n"
96 " --list-conversions\t\tList all possible conversions\n"
97 " --pop\t\t\t\tRestore the original loaded image\n"
98 " --read file[,attrlist]\tRead an input file\n"
99 " --slice x,y,w,h\t\tGenerate a slice from the loaded bitmap\n"
100 " --verbose\t\t\tIncrease verbosity\n"
101 " --version\t\t\tPrint the version number and exit\n"
102 " --write file[,attrlist]\tWrite the output to a file\n",
108 static void SetWorkBitmap (Bitmap* N)
109 /* Delete an old working bitmap and set a new one. The new one may be NULL
113 /* If we have a distinct work bitmap, delete it */
114 if (C != 0 && C != B) {
118 /* Set the new one */
124 static void SetOutputData (StrBuf* N)
125 /* Delete the old output data and replace it by the given one. The new one
126 * may be NULL to clear it.
129 /* Delete the old output data */
134 /* Set the new one */
140 static void OptConvertTo (const char* Opt attribute ((unused)), const char* Arg)
141 /* Convert the bitmap into a target format */
143 static const char* NameList[] = {
147 /* Parse the argument */
148 Collection* A = ParseAttrList (Arg, NameList, 2);
150 /* We must have a bitmap */
152 Error ("No bitmap to convert");
155 /* Convert the bitmap */
156 SetOutputData (ConvertTo (C, A));
158 /* Delete the attribute list */
164 static void OptDumpPalette (const char* Opt attribute ((unused)),
165 const char* Arg attribute ((unused)))
166 /* Dump the palette of the current work bitmap */
168 /* We must have a bitmap ... */
173 /* ... which must be indexed */
174 if (!BitmapIsIndexed (C)) {
175 Error ("Current bitmap is not indexed");
178 /* Dump the palette */
179 DumpPalette (stdout, GetBitmapPalette (C));
184 static void OptHelp (const char* Opt attribute ((unused)),
185 const char* Arg attribute ((unused)))
186 /* Print usage information and exit */
194 static void OptListConversions (const char* Opt attribute ((unused)),
195 const char* Arg attribute ((unused)))
196 /* Print a list of all conversions */
198 ListConversionTargets (stdout);
204 static void OptPop (const char* Opt attribute ((unused)),
205 const char* Arg attribute ((unused)))
206 /* Restore the original image */
208 /* C and B must differ and we must have an original */
209 if (B == 0 || C == 0 || C == B) {
210 Error ("Nothing to pop");
213 /* Delete the changed image and restore the original one */
219 static void OptRead (const char* Opt attribute ((unused)), const char* Arg)
220 /* Read an input file */
222 static const char* NameList[] = {
227 /* Parse the argument */
228 Collection* A = ParseAttrList (Arg, NameList, 2);
230 /* Clear the working copy */
233 /* Delete the original */
236 /* Read the file and use it as original and as working copy */
237 B = C = ReadInputFile (A);
239 /* Delete the attribute list */
245 static void OptSlice (const char* Opt attribute ((unused)), const char* Arg)
246 /* Generate a slice of a bitmap */
251 /* We must have a bitmap otherwise we cannot slice */
253 Error ("Nothing to slice");
256 /* The argument is X,Y,W,H */
257 if (sscanf (Arg, "%u,%u,%u,%u,%c", &X, &Y, &W, &H, &T) != 4) {
258 Error ("Invalid argument. Slice must be given as X,Y,W,H");
261 /* Check the coordinates to be within the original bitmap */
262 if (W > BM_MAX_WIDTH || H > BM_MAX_HEIGHT ||
263 X + W > GetBitmapWidth (C) ||
264 Y + H > GetBitmapHeight (C)) {
265 Error ("Invalid slice coordinates and/or size");
268 /* Create the slice */
269 SetWorkBitmap (SliceBitmap (C, X, Y, W, H));
274 static void OptVerbose (const char* Opt attribute ((unused)),
275 const char* Arg attribute ((unused)))
276 /* Increase versbosity */
283 static void OptVersion (const char* Opt attribute ((unused)),
284 const char* Arg attribute ((unused)))
285 /* Print the assembler version */
287 fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ());
292 static void OptWrite (const char* Opt attribute ((unused)), const char* Arg)
293 /* Write an output file */
295 static const char* NameList[] = {
300 /* Parse the argument */
301 Collection* A = ParseAttrList (Arg, NameList, 2);
303 /* We must have output data */
305 Error ("No conversion, so there's nothing to write");
309 WriteOutputFile (D, A, C);
311 /* Delete the attribute list */
317 int main (int argc, char* argv [])
318 /* sp65 main program */
320 /* Program long options */
321 static const LongOpt OptTab[] = {
322 { "--convert-to", 1, OptConvertTo },
323 { "--dump-palette", 0, OptDumpPalette },
324 { "--help", 0, OptHelp },
325 { "--list-conversions", 0, OptListConversions },
326 { "--pop", 0, OptPop },
327 { "--read", 1, OptRead },
328 { "--slice", 1, OptSlice },
329 { "--verbose", 0, OptVerbose },
330 { "--version", 0, OptVersion },
331 { "--write", 1, OptWrite },
336 /* Initialize the cmdline module */
337 InitCmdLine (&argc, &argv, "sp65");
339 /* Check the parameters */
341 while (I < ArgCount) {
343 /* Get the argument */
344 const char* Arg = ArgVec[I];
346 /* Check for an option */
351 LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
359 OptConvertTo (Arg, GetArg (&I, 2));
368 OptListConversions (Arg, 0);
375 OptRead (Arg, GetArg (&I, 2));
383 OptWrite (Arg, GetArg (&I, 2));
392 /* We don't accept anything else */
393 AbEnd ("Don't know what to do with `%s'", Arg);