Пример #1
0
// ---------------------------------------------------------
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());

}
Пример #3
0
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;
}