// --------------------------------------------------------- void KMahjongg::setupKAction() { // game KStdGameAction::gameNew(this, SLOT(newGame()), actionCollection()); KStdGameAction::load(this, SLOT(loadGame()), actionCollection()); KStdGameAction::save(this, SLOT(saveGame()), actionCollection()); KStdGameAction::quit(this, SLOT(close()), actionCollection()); KStdGameAction::restart(this, SLOT(restartGame()), actionCollection()); new KAction(i18n("New Numbered Game..."), "newnum", 0, this, SLOT(startNewNumeric()), actionCollection(), "game_new_numeric"); new KAction(i18n("Open Th&eme..."), 0, this, SLOT(openTheme()), actionCollection(), "game_open_theme"); new KAction(i18n("Open &Tileset..."), 0, this, SLOT(openTileset()), actionCollection(), "game_open_tileset"); new KAction(i18n("Open &Background..."), 0, this, SLOT(openBackground()), actionCollection(), "game_open_background"); new KAction(i18n("Open La&yout..."), 0, this, SLOT(openLayout()), actionCollection(), "game_open_layout"); new KAction(i18n("Sa&ve Theme..."), 0, this, SLOT(saveTheme()), actionCollection(), "game_save_theme"); // originally "file" ends here KStdGameAction::hint(bw, SLOT(helpMove()), actionCollection()); new KAction(i18n("Shu&ffle"), "reload", 0, bw, SLOT(shuffle()), actionCollection(), "move_shuffle"); demoAction = KStdGameAction::demo(this, SLOT(demoMode()), actionCollection()); showMatchingTilesAction = new KToggleAction(i18n("Show &Matching Tiles"), 0, this, SLOT(showMatchingTiles()), actionCollection(), "options_show_matching_tiles"); showMatchingTilesAction->setCheckedState(i18n("Hide &Matching Tiles")); showMatchingTilesAction->setChecked(Prefs::showMatchingTiles()); bw->setShowMatch( Prefs::showMatchingTiles() ); KStdGameAction::highscores(this, SLOT(showHighscores()), actionCollection()); pauseAction = KStdGameAction::pause(this, SLOT(pause()), actionCollection()); // TODO: store the background ; open on startup // TODO: same about layout // TODO: same about theme // move undoAction = KStdGameAction::undo(this, SLOT(undo()), actionCollection()); redoAction = KStdGameAction::redo(this, SLOT(redo()), actionCollection()); // edit new KAction(i18n("&Board Editor"), 0, this, SLOT(slotBoardEditor()), actionCollection(), "edit_board_editor"); // settings KStdAction::preferences(this, SLOT(showSettings()), actionCollection()); setupGUI(); }
void TilesetConfigureDialog::on_OpenTileset_clicked() { QString openPath; switch(mode) { case GFX_Level: openPath = dynamic_cast<LvlScene *>(scn)->LvlData->path+"/"; break; case GFX_World: openPath = dynamic_cast<WldScene *>(scn)->WldData->path+"/"; break; default: openPath = m_conf->config_dir + "tilesets/"; } QString fileName = QFileDialog::getOpenFileName(this, tr("Open Tileset"), openPath, QString("PGE Tileset (*.tileset.ini)")); if (fileName.isEmpty()) return; openTileset(fileName, ui->customOnly->isChecked()); }
int main(int iArgC, char *cArgV[]) { #ifdef __GLIBCXX__ // Set a better exception handler std::set_terminate(__gnu_cxx::__verbose_terminate_handler); #endif // Disable stdin/printf/etc. sync for a speed boost std::ios_base::sync_with_stdio(false); // Declare the supported options. po::options_description poActions("Actions"); poActions.add_options() ("info,i", "display information about the map, including attributes/metadata") ("print,p", po::value<int>(), "print the given layer in ASCII") ("render,r", po::value<std::string>(), "render the map to the given .png file") ; po::options_description poOptions("Options"); poOptions.add_options() ("type,t", po::value<std::string>(), "specify the map type (default is autodetect)") ("graphics,g", po::value<std::string>(), "filename storing game graphics (required with --render)") ("script,s", "format output suitable for script parsing") ("force,f", "force open even if the map is not in the given format") ("list-types", "list supported file types") ; po::options_description poHidden("Hidden parameters"); poHidden.add_options() ("map", "map file to manipulate") ("help", "produce help message") ; po::options_description poVisible(""); poVisible.add(poActions).add(poOptions); po::options_description poComplete("Parameters"); poComplete.add(poActions).add(poOptions).add(poHidden); po::variables_map mpArgs; std::string strFilename, strType; std::map<gm::ImagePurpose, gm::Map::GraphicsFilename> manualGfx; bool bScript = false; // show output suitable for script parsing? bool bForceOpen = false; // open anyway even if map not in given format? int iRet = RET_OK; try { po::parsed_options pa = po::parse_command_line(iArgC, cArgV, poComplete); // Parse the global command line options for (auto& i : pa.options) { if (i.string_key.empty()) { // If we've already got an map filename, complain that a second one // was given (probably a typo.) if (!strFilename.empty()) { std::cerr << "Error: unexpected extra parameter (multiple map " "filenames given?!)" << std::endl; return 1; } assert(i.value.size() > 0); // can't have no values with no name! strFilename = i.value[0]; } else if (i.string_key.compare("help") == 0) { std::cout << "Copyright (C) 2010-2015 Adam Nielsen <*****@*****.**>\n" "This program comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "and you are welcome to change and redistribute it under certain conditions;\n" "see <http://www.gnu.org/licenses/> for details.\n" "\n" "Utility to manipulate map files used by games to store data files.\n" "Build date " __DATE__ " " __TIME__ << "\n" "\n" "Usage: gamemap <map> <action> [action...]\n" << poVisible << "\n" << std::endl; return RET_OK; } else if ( (i.string_key.compare("t") == 0) || (i.string_key.compare("type") == 0) ) { strType = i.value[0]; } else if ( (i.string_key.compare("g") == 0) || (i.string_key.compare("graphics") == 0) ) { std::string purpose, temp; gm::Map::GraphicsFilename gf; bool a = split(i.value[0], '=', &purpose, &temp); bool b = split(temp, ':', &gf.type, &gf.filename); if (!a || !b) { std::cerr << "Malformed -g/--graphics parameter. Must be of the " "form purpose=type:filename.\n" "Use --help or --list-types for details." << std::endl; return RET_BADARGS; } bool found = false; for (unsigned int i = 0; i < (unsigned int)gm::ImagePurpose::ImagePurposeCount; i++) { gm::ImagePurpose p = (gm::ImagePurpose)i; if (purpose.compare(toString(p)) == 0) { manualGfx[p] = gf; found = true; } } if (!found) { std::cerr << "No match for tileset purpose: " << purpose << "\n" << "Use --list-types for details." << std::endl; return RET_BADARGS; } } else if ( (i.string_key.compare("s") == 0) || (i.string_key.compare("script") == 0) ) { bScript = true; } else if ( (i.string_key.compare("f") == 0) || (i.string_key.compare("force") == 0) ) { bForceOpen = true; } else if ( (i.string_key.compare("list-types") == 0) ) { std::cout << "Tileset purposes: (--graphics purpose=type:file)\n"; for (unsigned int i = 0; i < (unsigned int)gm::ImagePurpose::ImagePurposeCount; i++) { gm::ImagePurpose p = (gm::ImagePurpose)i; std::cout << " " << toString(p) << "\n"; } std::cout << "\nTileset types: (--graphics purpose=type:file)\n"; for (auto& tilesetType : gg::TilesetManager::formats()) { std::string code = tilesetType->code(); std::cout << " " << code; int len = code.length(); if (len < 20) std::cout << std::string(20-code.length(), ' '); std::cout << ' ' << tilesetType->friendlyName(); auto ext = tilesetType->fileExtensions(); if (ext.size()) { auto i = ext.begin(); std::cout << " (*." << *i; for (i++; i != ext.end(); i++) { std::cout << "; *." << *i; } std::cout << ")"; } std::cout << '\n'; } std::cout << "\nMap types: (--type)\n"; for (auto& mapType : gm::MapManager::formats()) { std::string code = mapType->code(); std::cout << " " << code; int len = code.length(); if (len < 20) std::cout << std::string(20 - code.length(), ' '); std::cout << ' ' << mapType->friendlyName(); auto ext = mapType->fileExtensions(); if (ext.size()) { auto i = ext.begin(); std::cout << " (*." << *i; for (i++; i != ext.end(); i++) { std::cout << "; *." << *i; } std::cout << ")"; } std::cout << '\n'; } return RET_OK; } } if (strFilename.empty()) { std::cerr << "Error: no game map filename given" << std::endl; return RET_BADARGS; } std::cout << "Opening " << strFilename << " as type " << (strType.empty() ? "<autodetect>" : strType) << std::endl; std::unique_ptr<stream::inout> content; try { content = std::make_unique<stream::file>(strFilename, false); } catch (const stream::open_error& e) { std::cerr << "Error opening " << strFilename << ": " << e.what() << std::endl; return RET_SHOWSTOPPER; } gm::MapManager::handler_t mapType; if (strType.empty()) { // Need to autodetect the file format. for (auto& mapTestType : gm::MapManager::formats()) { gm::MapType::Certainty cert = mapTestType->isInstance(*content); switch (cert) { case gm::MapType::Certainty::DefinitelyNo: // Don't print anything (TODO: Maybe unless verbose?) break; case gm::MapType::Certainty::Unsure: std::cout << "File could be a " << mapTestType->friendlyName() << " [" << mapTestType->code() << "]" << std::endl; // If we haven't found a match already, use this one if (!mapType) mapType = mapTestType; break; case gm::MapType::Certainty::PossiblyYes: std::cout << "File is likely to be a " << mapTestType->friendlyName() << " [" << mapTestType->code() << "]" << std::endl; // Take this one as it's better than an uncertain match mapType = mapTestType; break; case gm::MapType::Certainty::DefinitelyYes: std::cout << "File is definitely a " << mapTestType->friendlyName() << " [" << mapTestType->code() << "]" << std::endl; mapType = mapTestType; // Don't bother checking any other formats if we got a 100% match goto finishTesting; } if (cert != gm::MapType::Certainty::DefinitelyNo) { // We got a possible match, see if it requires any suppdata auto suppList = mapTestType->getRequiredSupps(*content, strFilename); if (suppList.size() > 0) { // It has suppdata, see if it's present std::cout << " * This format requires supplemental files..." << std::endl; bool bSuppOK = true; for (auto& i : suppList) { try { auto suppStream = std::make_unique<stream::file>(i.second, false); } catch (const stream::open_error&) { bSuppOK = false; std::cout << " * Could not find/open " << i.second << ", map is probably not " << mapTestType->code() << std::endl; break; } } if (bSuppOK) { // All supp files opened ok std::cout << " * All supp files present, map is likely " << mapTestType->code() << std::endl; // Set this as the most likely format mapType = mapTestType; } } } } finishTesting: if (!mapType) { std::cerr << "Unable to automatically determine the file type. Use " "the --type option to manually specify the file format." << std::endl; return RET_BE_MORE_SPECIFIC; } } else { mapType = gm::MapManager::byCode(strType); if (!mapType) { std::cerr << "Unknown file type given to -t/--type: " << strType << std::endl; return RET_BADARGS; } } assert(mapType != NULL); // Check to see if the file is actually in this format if (!mapType->isInstance(*content)) { if (bForceOpen) { std::cerr << "Warning: " << strFilename << " is not a " << mapType->friendlyName() << ", open forced." << std::endl; } else { std::cerr << "Invalid format: " << strFilename << " is not a " << mapType->friendlyName() << "\n" << "Use the -f option to try anyway." << std::endl; return RET_BE_MORE_SPECIFIC; } } // See if the format requires any supplemental files camoto::SuppData suppData; for (auto& i : mapType->getRequiredSupps(*content, strFilename)) { try { std::cerr << "Opening supplemental file " << i.second << std::endl; suppData[i.first] = std::make_unique<stream::file>(i.second, false); } catch (const stream::open_error& e) { std::cerr << "Error opening supplemental file " << i.second << ": " << e.what() << std::endl; // Continue anyway in case the file is optional } } // Open the map file std::shared_ptr<gm::Map> pMap = mapType->open(std::move(content), suppData); assert(pMap); // File type of inserted files defaults to empty, which means 'generic file' std::string strLastFiletype; // Run through the actions on the command line for (auto& i : pa.options) { if (i.string_key.compare("info") == 0) { listAttributes(pMap.get(), bScript); std::cout << (bScript ? "gfx_filename_count=" : "Number of graphics filenames: ") << pMap->graphicsFilenames().size() << "\n"; int fileNum = 0; for (auto& a : pMap->graphicsFilenames()) { if (bScript) { std::cout << "gfx_file" << fileNum << "_name=" << a.second.filename << "\n"; std::cout << "gfx_file" << fileNum << "_type=" << a.second.type << "\n"; std::cout << "gfx_file" << fileNum << "_purpose=" << (unsigned int)a.first << "\n"; } else { std::cout << "Graphics file " << fileNum+1 << ": " << a.second.filename << " ["; switch (a.first) { case gm::ImagePurpose::GenericTileset1: std::cout << "Generic tileset 1"; break; case gm::ImagePurpose::BackgroundImage: std::cout << "Background image"; break; case gm::ImagePurpose::BackgroundTileset1: std::cout << "Background tileset 1"; break; case gm::ImagePurpose::BackgroundTileset2: std::cout << "Background tileset 2"; break; case gm::ImagePurpose::ForegroundTileset1: std::cout << "Foreground tileset 1"; break; case gm::ImagePurpose::ForegroundTileset2: std::cout << "Foreground tileset 2"; break; case gm::ImagePurpose::SpriteTileset1: std::cout << "Sprite tileset 1"; break; case gm::ImagePurpose::FontTileset1: std::cout << "Font tileset 1"; break; case gm::ImagePurpose::FontTileset2: std::cout << "Font tileset 2"; break; default: std::cout << "Unknown purpose <fix this>"; break; } std::cout << " of type " << a.second.type << "]\n"; } fileNum++; } std::cout << (bScript ? "map_type=" : "Map type: "); auto map2d = std::dynamic_pointer_cast<gm::Map2D>(pMap); if (map2d) { std::cout << (bScript ? "2d" : "2D grid-based") << "\n"; #define CAP(o, c, v) " " __STRING(c) << ((v & o::Caps::c) ? '+' : '-') #define MAP2D_CAP(c) CAP(gm::Map2D, c, mapCaps) #define MAP2D_LAYER_CAP(c) CAP(gm::Map2D::Layer, c, layerCaps) auto mapCaps = map2d->caps(); if (bScript) { std::cout << "map_caps=" << (unsigned int)mapCaps << "\n"; } else { std::cout << "Map capabilities:" << MAP2D_CAP(HasViewport) << MAP2D_CAP(HasMapSize) << MAP2D_CAP(SetMapSize) << MAP2D_CAP(HasTileSize) << MAP2D_CAP(SetTileSize) << MAP2D_CAP(AddPaths) << "\n" ; } auto mapTileSize = map2d->tileSize(); std::cout << (bScript ? "tile_width=" : "Tile size: ") << mapTileSize.x << (bScript ? "\ntile_height=" : "x") << mapTileSize.y << "\n"; auto mapSize = map2d->mapSize(); std::cout << (bScript ? "map_width=" : "Map size: ") << mapSize.x << (bScript ? "\nmap_height=" : "x") << mapSize.y << (bScript ? "" : " tiles") << "\n"; if (mapCaps & gm::Map2D::Caps::HasViewport) { auto vp = map2d->viewport(); std::cout << (bScript ? "viewport_width=" : "Viewport size: ") << vp.x << (bScript ? "\nviewport_height=" : "x") << vp.y << (bScript ? "" : " pixels") << "\n"; } unsigned int layerCount = map2d->layers().size(); std::cout << (bScript ? "layercount=" : "Layer count: ") << layerCount << "\n"; unsigned int layerIndex = 0; for (auto& layer : map2d->layers()) { std::string prefix; if (bScript) { std::stringstream ss; ss << "layer" << layerIndex << '_'; prefix = ss.str(); std::cout << prefix << "name=" << layer->title() << "\n"; } else { prefix = " "; std::cout << "Layer " << layerIndex + 1 << ": \"" << layer->title() << "\"\n"; } auto layerCaps = layer->caps(); if (bScript) std::cout << prefix << "caps=" << (unsigned int)layerCaps << "\n"; else std::cout << prefix << "Capabilities:" << MAP2D_LAYER_CAP(HasOwnSize) << MAP2D_LAYER_CAP(SetOwnSize) << MAP2D_LAYER_CAP(HasOwnTileSize) << MAP2D_LAYER_CAP(SetOwnTileSize) << MAP2D_LAYER_CAP(HasPalette) << MAP2D_LAYER_CAP(UseImageDims) << "\n" ; gg::Point layerTileSize; bool layerTileSame; if (layerCaps & gm::Map2D::Layer::Caps::HasOwnTileSize) { layerTileSize = layer->tileSize(); layerTileSame = false; } else { layerTileSize = mapTileSize; layerTileSame = true; } std::cout << prefix << (bScript ? "tile_width=" : "Tile size: ") << layerTileSize.x; if (bScript) std::cout << "\n" << prefix << "tile_height="; else std::cout << "x"; std::cout << layerTileSize.y; if (layerTileSame && (!bScript)) { std::cout << " (same as map)"; } std::cout << "\n"; gg::Point layerSize; bool layerSame; if (layerCaps & gm::Map2D::Layer::Caps::HasOwnSize) { layerSize = layer->layerSize(); layerSame = false; } else { // Convert from map tilesize to layer tilesize, leaving final // pixel dimensions unchanged layerSize.x = mapSize.x * mapTileSize.x / layerTileSize.x; layerSize.y = mapSize.y * mapTileSize.y / layerTileSize.y; layerSame = true; } std::cout << prefix << (bScript ? "width=" : "Layer size: ") << layerSize.x; if (bScript) std::cout << "\n" << prefix << "height="; else std::cout << "x"; std::cout << layerSize.y; if (layerSame && (!bScript)) { std::cout << " (same as map)"; } std::cout << "\n"; layerIndex++; } } else { std::cout << (bScript ? "unknown" : "Unknown! Fix this!") << "\n"; } } else if (i.string_key.compare("print") == 0) { auto map2d = std::dynamic_pointer_cast<gm::Map2D>(pMap); if (map2d) { unsigned int targetLayer = strtoul(i.value[0].c_str(), NULL, 10); if (targetLayer == 0) { std::cerr << "Invalid layer index passed to --print. Use --info " "to list layers in this map." << std::endl; iRet = RET_BADARGS; continue; } if (targetLayer > map2d->layers().size()) { std::cerr << "Invalid layer index passed to --print. Use --info " "to list layers in this map." << std::endl; iRet = RET_BADARGS; continue; } auto layer = map2d->layers().at(targetLayer - 1); // If this fails, the map format returned a null pointer for the layer assert(layer); // Figure out the layer size gg::Point layerSize, tileSize; getLayerDims(*map2d, *layer, &layerSize, &tileSize); auto items = layer->items(); auto t = items.begin(); unsigned int numItems = items.size(); if (t != items.end()) { for (unsigned int y = 0; y < layerSize.y; y++) { for (unsigned int x = 0; x < layerSize.x; x++) { for (unsigned int i = 0; i < numItems; i++) { if ((t->pos.x == x) && (t->pos.y == y)) break; t++; if (t == items.end()) t = items.begin(); } if ((t->pos.x != x) || (t->pos.y != y)) { // Grid position with no tile! std::cout << " "; } else { std::cout << std::hex << std::setw(4) << (unsigned int)t->code << ' '; } } std::cout << "\n"; } } else { std::cout << "Layer is empty!" << std::endl; } } else { std::cerr << "Support for printing this map type has not yet " "been implemented!" << std::endl; } } else if (i.string_key.compare("render") == 0) { // Don't need to check i.value[0], program_options does that for us auto map2d = std::dynamic_pointer_cast<gm::Map2D>(pMap); if (map2d) { gm::TilesetCollection allTilesets; for (auto& a : manualGfx) { if (!bScript) { std::cout << "Loading " << a.second.type << " from " << a.second.filename << std::endl; } allTilesets[a.first] = openTileset(a.second.filename, a.second.type); } for (auto& a : pMap->graphicsFilenames()) { if (allTilesets.find(a.first) == allTilesets.end()) { if (a.second.filename.empty()) { std::cerr << toString(a.first) << " is required, and must " "be specified manually with --graphics." << std::endl; iRet = RET_BADARGS; } else { // This tileset hasn't been specified on the command line, but the // map format handler has given us a filename, so open the file // suggested from the map. allTilesets[a.first] = openTileset(a.second.filename, a.second.type); } } else { if (!a.second.filename.empty()) { std::cout << toString(a.first) << " overridden on command-line\n"; } } } if (allTilesets.empty()) { std::cerr << "No tilesets were loaded, map cannot be rendered. " "Use --graphics to specify a tileset." << std::endl; iRet = RET_BADARGS; } else { map2dToPng(*map2d, allTilesets, i.value[0]); } } else { std::cerr << PROGNAME ": Rendering this type of map is not yet " "implemented." << std::endl; return RET_SHOWSTOPPER; } // Ignore --type/-t } else if (i.string_key.compare("type") == 0) { } else if (i.string_key.compare("t") == 0) { // Ignore --script/-s } else if (i.string_key.compare("script") == 0) { } else if (i.string_key.compare("s") == 0) { // Ignore --force/-f } else if (i.string_key.compare("force") == 0) { } else if (i.string_key.compare("f") == 0) { } } // for (all command line elements) //pMap->flush(); } catch (const po::error& e) { std::cerr << PROGNAME ": " << e.what() << " Use --help for help." << std::endl; return RET_BADARGS; } catch (const stream::error& e) { std::cerr << PROGNAME ": " << e.what() << " Use --help for help." << std::endl; return RET_SHOWSTOPPER; } return iRet; }