| 1 | // Aseprite |
| 2 | // Copyright (C) 2018-2022 Igara Studio S.A. |
| 3 | // Copyright (C) 2001-2017 David Capello |
| 4 | // |
| 5 | // This program is distributed under the terms of |
| 6 | // the End-User License Agreement for Aseprite. |
| 7 | |
| 8 | #ifdef HAVE_CONFIG_H |
| 9 | #include "config.h" |
| 10 | #endif |
| 11 | |
| 12 | #include "app/cli/app_options.h" |
| 13 | |
| 14 | #include "base/fs.h" |
| 15 | |
| 16 | #include <iostream> |
| 17 | |
| 18 | namespace app { |
| 19 | |
| 20 | AppOptions::AppOptions(int argc, const char* argv[]) |
| 21 | : m_exeName(base::get_file_name(argv[0])) |
| 22 | , m_startUI(true) |
| 23 | , m_startShell(false) |
| 24 | , m_previewCLI(false) |
| 25 | , m_showHelp(false) |
| 26 | , m_showVersion(false) |
| 27 | , m_verboseLevel(kNoVerbose) |
| 28 | #ifdef ENABLE_SCRIPTING |
| 29 | , m_shell(m_po.add("shell" ).description("Start an interactive console to execute scripts" )) |
| 30 | #endif |
| 31 | , m_batch(m_po.add("batch" ).mnemonic('b').description("Do not start the UI" )) |
| 32 | , m_preview(m_po.add("preview" ).mnemonic('p').description("Do not execute actions, just print what will be\ndone" )) |
| 33 | , m_saveAs(m_po.add("save-as" ).requiresValue("<filename>" ).description("Save the last given sprite with other format" )) |
| 34 | , m_palette(m_po.add("palette" ).requiresValue("<filename>" ).description("Change the palette of the last given sprite" )) |
| 35 | , m_scale(m_po.add("scale" ).requiresValue("<factor>" ).description("Resize all previously opened sprites" )) |
| 36 | , m_ditheringAlgorithm(m_po.add("dithering-algorithm" ).requiresValue("<algorithm>" ).description("Dithering algorithm used in --color-mode\nto convert images from RGB to Indexed\n none\n ordered\n old" )) |
| 37 | , m_ditheringMatrix(m_po.add("dithering-matrix" ).requiresValue("<id>" ).description("Matrix used in ordered dithering algorithm\n bayer2x2\n bayer4x4\n bayer8x8\n filename.png" )) |
| 38 | , m_colorMode(m_po.add("color-mode" ).requiresValue("<mode>" ).description("Change color mode of all previously\nopened sprites:\n rgb\n grayscale\n indexed" )) |
| 39 | , m_shrinkTo(m_po.add("shrink-to" ).requiresValue("width,height" ).description("Shrink each sprite if it is\nlarger than width or height" )) |
| 40 | , m_data(m_po.add("data" ).requiresValue("<filename.json>" ).description("File to store the sprite sheet metadata" )) |
| 41 | , m_format(m_po.add("format" ).requiresValue("<format>" ).description("Format to export the data file\n(json-hash, json-array)" )) |
| 42 | , m_sheet(m_po.add("sheet" ).requiresValue("<filename.png>" ).description("Image file to save the texture" )) |
| 43 | , m_sheetType(m_po.add("sheet-type" ).requiresValue("<type>" ).description("Algorithm to create the sprite sheet:\n horizontal\n vertical\n rows\n columns\n packed" )) |
| 44 | , m_sheetPack(m_po.add("sheet-pack" ).description("Same as -sheet-type packed" )) |
| 45 | , m_sheetWidth(m_po.add("sheet-width" ).requiresValue("<pixels>" ).description("Sprite sheet width" )) |
| 46 | , m_sheetHeight(m_po.add("sheet-height" ).requiresValue("<pixels>" ).description("Sprite sheet height" )) |
| 47 | , m_sheetColumns(m_po.add("sheet-columns" ).requiresValue("<columns>" ).description("Fixed # of columns for -sheet-type rows" )) |
| 48 | , m_sheetRows(m_po.add("sheet-rows" ).requiresValue("<rows>" ).description("Fixed # of rows for -sheet-type columns" )) |
| 49 | , m_splitLayers(m_po.add("split-layers" ).description("Save each visible layer of sprites\nas separated images in the sheet\n" )) |
| 50 | , m_splitTags(m_po.add("split-tags" ).description("Save each tag as a separated file" )) |
| 51 | , m_splitSlices(m_po.add("split-slices" ).description("Save each slice as a separated file" )) |
| 52 | , m_splitGrid(m_po.add("split-grid" ).description("Save each grid tile as a separated file" )) |
| 53 | , m_layer(m_po.add("layer" ).alias("import-layer" ).requiresValue("<name>" ).description("Include just the given layer in the sheet\nor save as operation" )) |
| 54 | , m_allLayers(m_po.add("all-layers" ).description("Make all layers visible\nBy default hidden layers will be ignored" )) |
| 55 | , m_ignoreLayer(m_po.add("ignore-layer" ).requiresValue("<name>" ).description("Exclude the given layer in the sheet\nor save as operation" )) |
| 56 | , m_tag(m_po.add("tag" ).alias("frame-tag" ).requiresValue("<name>" ).description("Include tagged frames in the sheet" )) |
| 57 | , m_frameRange(m_po.add("frame-range" ).requiresValue("from,to" ).description("Only export frames in the [from,to] range" )) |
| 58 | , m_ignoreEmpty(m_po.add("ignore-empty" ).description("Do not export empty frames/cels" )) |
| 59 | , m_mergeDuplicates(m_po.add("merge-duplicates" ).description("Merge all duplicate frames into one in the sprite sheet" )) |
| 60 | , m_borderPadding(m_po.add("border-padding" ).requiresValue("<value>" ).description("Add padding on the texture borders" )) |
| 61 | , m_shapePadding(m_po.add("shape-padding" ).requiresValue("<value>" ).description("Add padding between frames" )) |
| 62 | , m_innerPadding(m_po.add("inner-padding" ).requiresValue("<value>" ).description("Add padding inside each frame" )) |
| 63 | , m_trim(m_po.add("trim" ).description("Trim whole sprite for --save-as\nor individual frames for --sheet" )) |
| 64 | , m_trimSprite(m_po.add("trim-sprite" ).description("Trim the whole sprite (for --save-as and --sheet)" )) |
| 65 | , m_trimByGrid(m_po.add("trim-by-grid" ).description("Trim all images by its correspondent grid boundaries before exporting" )) |
| 66 | , m_extrude(m_po.add("extrude" ).description("Extrude all images duplicating all edges one pixel" )) |
| 67 | , m_crop(m_po.add("crop" ).requiresValue("x,y,width,height" ).description("Crop all the images to the given rectangle" )) |
| 68 | , m_slice(m_po.add("slice" ).requiresValue("<name>" ).description("Crop the sprite to the given slice area" )) |
| 69 | , m_filenameFormat(m_po.add("filename-format" ).requiresValue("<fmt>" ).description("Special format to generate filenames" )) |
| 70 | #ifdef ENABLE_SCRIPTING |
| 71 | , m_script(m_po.add("script" ).requiresValue("<filename>" ).description("Execute a specific script" )) |
| 72 | , m_scriptParam(m_po.add("script-param" ).requiresValue("name=value" ).description("Parameter for a script executed from the\nCLI that you can access with app.params" )) |
| 73 | #endif |
| 74 | , m_listLayers(m_po.add("list-layers" ).description("List layers of the next given sprite\nor include layers in JSON data" )) |
| 75 | , m_listTags(m_po.add("list-tags" ).description("List tags of the next given sprite\nor include frame tags in JSON data" )) |
| 76 | , m_listSlices(m_po.add("list-slices" ).description("List slices of the next given sprite\nor include slices in JSON data" )) |
| 77 | , m_oneFrame(m_po.add("oneframe" ).description("Load just the first frame" )) |
| 78 | , m_exportTileset(m_po.add("export-tileset" ).description("Export only tilesets from visible tilemap layers" )) |
| 79 | , m_verbose(m_po.add("verbose" ).mnemonic('v').description("Explain what is being done" )) |
| 80 | , m_debug(m_po.add("debug" ).description("Extreme verbose mode and\ncopy log to desktop" )) |
| 81 | #ifdef _WIN32 |
| 82 | , m_disableWintab(m_po.add("disable-wintab" ).description("Don't load wintab32.dll library" )) |
| 83 | #endif |
| 84 | , m_help(m_po.add("help" ).mnemonic('?').description("Display this help and exits" )) |
| 85 | , m_version(m_po.add("version" ).description("Output version information and exit" )) |
| 86 | { |
| 87 | try { |
| 88 | m_po.parse(argc, argv); |
| 89 | |
| 90 | if (m_po.enabled(m_debug)) |
| 91 | m_verboseLevel = kHighlyVerbose; |
| 92 | else if (m_po.enabled(m_verbose)) |
| 93 | m_verboseLevel = kVerbose; |
| 94 | |
| 95 | #ifdef ENABLE_SCRIPTING |
| 96 | m_startShell = m_po.enabled(m_shell); |
| 97 | #endif |
| 98 | m_previewCLI = m_po.enabled(m_preview); |
| 99 | m_showHelp = m_po.enabled(m_help); |
| 100 | m_showVersion = m_po.enabled(m_version); |
| 101 | |
| 102 | if (m_startShell || |
| 103 | m_showHelp || |
| 104 | m_showVersion || |
| 105 | m_po.enabled(m_batch)) { |
| 106 | m_startUI = false; |
| 107 | } |
| 108 | } |
| 109 | catch (const std::runtime_error& parseError) { |
| 110 | std::cerr << m_exeName << ": " << parseError.what() << '\n' |
| 111 | << "Try \"" << m_exeName << " --help\" for more information.\n" ; |
| 112 | m_startUI = false; |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | bool AppOptions::hasExporterParams() const |
| 117 | { |
| 118 | return |
| 119 | m_po.enabled(m_data) || |
| 120 | m_po.enabled(m_sheet); |
| 121 | } |
| 122 | |
| 123 | #ifdef _WIN32 |
| 124 | bool AppOptions::disableWintab() const |
| 125 | { |
| 126 | return m_po.enabled(m_disableWintab); |
| 127 | } |
| 128 | #endif |
| 129 | |
| 130 | } |
| 131 | |