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 " -r file[,attrlist]\t\tRead an input file\n"
89 " -v\t\t\t\tIncrease verbosity\n"
90 " -w file[,attrlist]\t\tWrite the output to a file\n"
93 " --convert-to fmt[,attrlist]\tConvert into target format\n"
94 " --help\t\t\tHelp (this text)\n"
95 " --pop\t\t\t\tRestore the original loaded image\n"
96 " --read file[,attrlist]\tRead an input file\n"
97 " --slice x,y,w,h\t\tGenerate a slice from the loaded bitmap\n"
98 " --verbose\t\t\tIncrease verbosity\n"
99 " --version\t\t\tPrint the version number and exit\n"
100 " --write file[,attrlist]\tWrite the output to a file\n",
106 static void SetWorkBitmap (Bitmap* N)
107 /* Delete an old working bitmap and set a new one. The new one may be NULL
111 /* If we have a distinct work bitmap, delete it */
112 if (C != 0 && C != B) {
116 /* Set the new one */
122 static void SetOutputData (StrBuf* N)
123 /* Delete the old output data and replace it by the given one. The new one
124 * may be NULL to clear it.
127 /* Delete the old output data */
132 /* Set the new one */
138 static void OptConvertTo (const char* Opt attribute ((unused)), const char* Arg)
139 /* Convert the bitmap into a target format */
141 static const char* NameList[] = {
145 /* Parse the argument */
146 Collection* A = ParseAttrList (Arg, NameList, 2);
148 /* We must have a bitmap */
150 Error ("No bitmap to convert");
153 /* Convert the bitmap */
154 SetOutputData (ConvertTo (C, A));
156 /* Delete the attribute list */
162 static void OptHelp (const char* Opt attribute ((unused)),
163 const char* Arg attribute ((unused)))
164 /* Print usage information and exit */
172 static void OptPop (const char* Opt attribute ((unused)),
173 const char* Arg attribute ((unused)))
174 /* Restore the original image */
176 /* C and B must differ and we must have an original */
177 if (B == 0 || C == 0 || C == B) {
178 Error ("Nothing to pop");
181 /* Delete the changed image and restore the original one */
187 static void OptRead (const char* Opt, const char* Arg)
188 /* Read an input file */
190 static const char* NameList[] = {
195 /* Parse the argument */
196 Collection* A = ParseAttrList (Arg, NameList, 2);
198 /* Must have a file name given */
199 const char* FileName = NeedAttrVal (A, "name", Opt);
201 /* Determine the format of the input file */
203 const char* Format = GetAttrVal (A, "format");
205 IF = FindInputFormat (Format);
207 Error ("Unknown input format `%s'", Format);
211 /* Clear the working copy */
214 /* Delete the original */
217 /* Read the file and use it as original and as working copy */
218 B = C = ReadInputFile (FileName, IF);
220 /* Delete the attribute list */
226 static void OptSlice (const char* Opt attribute ((unused)), const char* Arg)
227 /* Generate a slice of a bitmap */
232 /* We must have a bitmap otherwise we cannot slice */
234 Error ("Nothing to slice");
237 /* The argument is X,Y,W,H */
238 if (sscanf (Arg, "%u,%u,%u,%u,%c", &X, &Y, &W, &H, &T) != 4) {
239 Error ("Invalid argument. Slice must be given as X,Y,W,H");
242 /* Check the coordinates to be within the original bitmap */
243 if (W > BM_MAX_WIDTH || H > BM_MAX_HEIGHT ||
244 X + W > GetBitmapWidth (C) ||
245 Y + H > GetBitmapHeight (C)) {
246 Error ("Invalid slice coordinates and/or size");
249 /* Create the slice */
250 SetWorkBitmap (SliceBitmap (C, X, Y, W, H));
255 static void OptVerbose (const char* Opt attribute ((unused)),
256 const char* Arg attribute ((unused)))
257 /* Increase versbosity */
264 static void OptVersion (const char* Opt attribute ((unused)),
265 const char* Arg attribute ((unused)))
266 /* Print the assembler version */
269 "%s V%s - (C) Copyright 2012, Ullrich von Bassewitz\n",
270 ProgName, GetVersionAsString ());
275 static void OptWrite (const char* Opt attribute ((unused)), const char* Arg)
276 /* Write an output file */
278 static const char* NameList[] = {
283 /* Parse the argument */
284 Collection* A = ParseAttrList (Arg, NameList, 2);
287 WriteOutputFile (D, A);
289 /* Delete the attribute list */
295 int main (int argc, char* argv [])
296 /* sp65 main program */
298 /* Program long options */
299 static const LongOpt OptTab[] = {
300 { "--convert-to", 1, OptConvertTo },
301 { "--help", 0, OptHelp },
302 { "--pop", 0, OptPop },
303 { "--read", 1, OptRead },
304 { "--slice", 1, OptSlice },
305 { "--verbose", 0, OptVerbose },
306 { "--version", 0, OptVersion },
307 { "--write", 1, OptWrite },
312 /* Initialize the cmdline module */
313 InitCmdLine (&argc, &argv, "sp65");
315 /* Check the parameters */
317 while (I < ArgCount) {
319 /* Get the argument */
320 const char* Arg = ArgVec[I];
322 /* Check for an option */
323 if (Arg [0] == '-') {
327 LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
335 OptConvertTo (Arg, GetArg (&I, 2));
343 OptRead (Arg, GetArg (&I, 2));
351 OptWrite (Arg, GetArg (&I, 2));
360 /* We don't accept anything else */
361 AbEnd ("Don't know what to do with `%s'", Arg);