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 " --dump-palette\t\tDump palette as table\n"
96 " --help\t\t\tHelp (this text)\n"
97 " --list-conversions\t\tList all possible conversions\n"
98 " --pop\t\t\t\tRestore the original loaded image\n"
99 " --read file[,attrlist]\tRead an input file\n"
100 " --slice x,y,w,h\t\tGenerate a slice from the loaded bitmap\n"
101 " --verbose\t\t\tIncrease verbosity\n"
102 " --version\t\t\tPrint the version number and exit\n"
103 " --write file[,attrlist]\tWrite the output to a file\n",
109 static void SetWorkBitmap (Bitmap* N)
110 /* Delete an old working bitmap and set a new one. The new one may be NULL
114 /* If we have a distinct work bitmap, delete it */
115 if (C != 0 && C != B) {
119 /* Set the new one */
125 static void SetOutputData (StrBuf* N)
126 /* Delete the old output data and replace it by the given one. The new one
127 ** may be NULL to clear it.
130 /* Delete the old output data */
135 /* Set the new one */
141 static void OptConvertTo (const char* Opt attribute ((unused)), const char* Arg)
142 /* Convert the bitmap into a target format */
144 static const char* NameList[] = {
148 /* Parse the argument */
149 Collection* A = ParseAttrList (Arg, NameList, 2);
151 /* We must have a bitmap */
153 Error ("No bitmap to convert");
156 /* Convert the bitmap */
157 SetOutputData (ConvertTo (C, A));
159 /* Delete the attribute list */
165 static void OptDumpPalette (const char* Opt attribute ((unused)),
166 const char* Arg attribute ((unused)))
167 /* Dump the palette of the current work bitmap */
169 /* We must have a bitmap ... */
174 /* ... which must be indexed */
175 if (!BitmapIsIndexed (C)) {
176 Error ("Current bitmap is not indexed");
179 /* Dump the palette */
180 DumpPalette (stdout, GetBitmapPalette (C));
185 static void OptHelp (const char* Opt attribute ((unused)),
186 const char* Arg attribute ((unused)))
187 /* Print usage information and exit */
195 static void OptListConversions (const char* Opt attribute ((unused)),
196 const char* Arg attribute ((unused)))
197 /* Print a list of all conversions */
199 ListConversionTargets (stdout);
205 static void OptPop (const char* Opt attribute ((unused)),
206 const char* Arg attribute ((unused)))
207 /* Restore the original image */
209 /* C and B must differ and we must have an original */
210 if (B == 0 || C == 0 || C == B) {
211 Error ("Nothing to pop");
214 /* Delete the changed image and restore the original one */
220 static void OptRead (const char* Opt attribute ((unused)), const char* Arg)
221 /* Read an input file */
223 static const char* NameList[] = {
228 /* Parse the argument */
229 Collection* A = ParseAttrList (Arg, NameList, 2);
231 /* Clear the working copy */
234 /* Delete the original */
237 /* Read the file and use it as original and as working copy */
238 B = C = ReadInputFile (A);
240 /* Delete the attribute list */
246 static void OptSlice (const char* Opt attribute ((unused)), const char* Arg)
247 /* Generate a slice of a bitmap */
252 /* We must have a bitmap otherwise we cannot slice */
254 Error ("Nothing to slice");
257 /* The argument is X,Y,W,H */
258 if (sscanf (Arg, "%u,%u,%u,%u,%c", &X, &Y, &W, &H, &T) != 4) {
259 Error ("Invalid argument. Slice must be given as X,Y,W,H");
262 /* Check the coordinates to be within the original bitmap */
263 if (W > BM_MAX_WIDTH || H > BM_MAX_HEIGHT ||
264 X + W > GetBitmapWidth (C) ||
265 Y + H > GetBitmapHeight (C)) {
266 Error ("Invalid slice coordinates and/or size");
269 /* Create the slice */
270 SetWorkBitmap (SliceBitmap (C, X, Y, W, H));
275 static void OptVerbose (const char* Opt attribute ((unused)),
276 const char* Arg attribute ((unused)))
277 /* Increase verbosity */
284 static void OptVersion (const char* Opt attribute ((unused)),
285 const char* Arg attribute ((unused)))
286 /* Print the assembler version */
288 fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ());
293 static void OptWrite (const char* Opt attribute ((unused)), const char* Arg)
294 /* Write an output file */
296 static const char* NameList[] = {
301 /* Parse the argument */
302 Collection* A = ParseAttrList (Arg, NameList, 2);
304 /* We must have output data */
306 Error ("No conversion, so there's nothing to write");
310 WriteOutputFile (D, A, C);
312 /* Delete the attribute list */
318 int main (int argc, char* argv [])
319 /* sp65 main program */
321 /* Program long options */
322 static const LongOpt OptTab[] = {
323 { "--convert-to", 1, OptConvertTo },
324 { "--dump-palette", 0, OptDumpPalette },
325 { "--help", 0, OptHelp },
326 { "--list-conversions", 0, OptListConversions },
327 { "--pop", 0, OptPop },
328 { "--read", 1, OptRead },
329 { "--slice", 1, OptSlice },
330 { "--verbose", 0, OptVerbose },
331 { "--version", 0, OptVersion },
332 { "--write", 1, OptWrite },
337 /* Initialize the cmdline module */
338 InitCmdLine (&argc, &argv, "sp65");
340 /* Check the parameters */
342 while (I < ArgCount) {
344 /* Get the argument */
345 const char* Arg = ArgVec[I];
347 /* Check for an option */
352 LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
360 OptConvertTo (Arg, GetArg (&I, 2));
369 OptListConversions (Arg, 0);
376 OptRead (Arg, GetArg (&I, 2));
384 OptWrite (Arg, GetArg (&I, 2));
393 /* We don't accept anything else */
394 AbEnd ("Don't know what to do with `%s'", Arg);
401 /* Do we have an input file? */
403 Error ("No input file");