Example #1
0
void EditGameDialog::close() {
	if (getResult()) {
		ConfMan.set("description", _descriptionWidget->getEditString(), _domain);

		Common::Language lang = (Common::Language)_langPopUp->getSelectedTag();
		if (lang < 0)
			ConfMan.removeKey("language", _domain);
		else
			ConfMan.set("language", Common::getLanguageCode(lang), _domain);

		String gamePath(_gamePathWidget->getLabel());
		if (!gamePath.empty())
			ConfMan.set("path", gamePath, _domain);

		String extraPath(_extraPathWidget->getLabel());
		if (!extraPath.empty() && (extraPath != _c("None", "path")))
			ConfMan.set("extrapath", extraPath, _domain);
		else
			ConfMan.removeKey("extrapath", _domain);

		String savePath(_savePathWidget->getLabel());
		if (!savePath.empty() && (savePath != _("Default")))
			ConfMan.set("savepath", savePath, _domain);
		else
			ConfMan.removeKey("savepath", _domain);

		Common::Platform platform = (Common::Platform)_platformPopUp->getSelectedTag();
		if (platform < 0)
			ConfMan.removeKey("platform", _domain);
		else
			ConfMan.set("platform", Common::getPlatformCode(platform), _domain);

		// Set the state of engine-specific checkboxes
		for (uint i = 0; i < _engineOptions.size(); i++) {
			ConfMan.setBool(_engineOptions[i].configOption, _engineCheckboxes[i]->getState(), _domain);
		}
	}
	OptionsDialog::close();
}
Example #2
0
bool MainPanel::OnList(ListPop *list, int index, gedString &text, int listId)
{
	if(listEditBox) 
	{
		delete listEditBox;
		listEditBox = NULL;
	}

	switch(listId)
	{
	case LS_FILE:
		{			
			if(text == "New Game")
			{
				/*<Odilon>
				  Verifica se nao foi feito nada, ainda, para
				  pedir confirmacao apenas se necessario.
				*/
				
				if (GameControl::Get()->Modified())
				{
					//<Odilon> Pequena correcao de Ingles...
					PanelQuestion *panel = new PanelQuestion("This will discard the current game.\nProceed anyway?");
					///PanelQuestion *panel = new PanelQuestion("This action will erase the current game.\nTo proceed?");
					
					if(panel->Wait() == OK_BUTTON)
					{
						GameControl::Get()->NewGame();
						UndoControl::Get()->Clear();
						lastScripts.Clear();

						
						ExportGame::ClearExportName();
						
						/*Close actor dialog*/
						ActorProperty::Destroy();
					}
					
					delete panel;
					
				}
				else  //nao eh necessario confirmar; nada foi feito.
				{
					/* Aqui estou repetindo o mesmo codigo acima,...
					   talvez seja melhor encontrar outra maneira de fazer isso,
					   ou talvez nao... */
			
					GameControl::Get()->NewGame();
					UndoControl::Get()->Clear();
					lastScripts.Clear();

					/*Close actor dialog*/
					ActorProperty::Destroy();
				}
				
			}
			else if(text == "Load")
			{
				new LoadSaveGame(LOAD_GAME);

				ExportGame::ClearExportName();
				
			}
			else if(text == "Merge")
			{
				new LoadSaveGame(MERGE_GAME);
			}
#ifdef USE_SYSTEM_FILE_DIALOG
			else if(text == "Save As...")
			{
				new LoadSaveGame(SAVE_GAME);
				ExportGame::ClearExportName();
			}
			else if(text == "Save")
			{
				if(Tutorial::IsOff())
				{
					gedString gamePath(GameControl::Get()->getGamePath());

					if(!gamePath.empty())
					{
						LoadSaveGame::Save(gamePath + DIR_SEP + GameControl::Get()->getGameName());
					}
					else
					{
						new LoadSaveGame(SAVE_GAME);
					}
				}
				else
				{
					new LoadSaveGame(SAVE_GAME);
				}
			}
#else
			else if(text == "Save")
			{
				new LoadSaveGame(SAVE_GAME);
			}
#endif			
			else if(text == "Export")
			{
				#ifdef GAME_EDITOR_PROFESSIONAL

				if(GenericScript::ParserAll())
				{
					new ExportGame();
				}
				else
				{
					new PanelInfo(GenericScript::GetError(), "Error", ALIGN_LEFT);
				}
				
				#else 
				new PanelInfo(GAME_EDITOR_VERSION_ERROR);
				#endif
			}
			else if(text == "Exit")
			{
				//Exit
				SDL_Event event;
				memset(&event, 0, sizeof(SDL_Event));
				event.quit.type = SDL_QUIT;
				SDL_PushEvent(&event);
			}
			else
			{
				//Recent file list
				gedString *sFile = (gedString *)listFile->GetItemData(index);
				if(sFile)
				{
					LoadGame(*sFile, true);
				}
			}		
		}
		break;
	case LS_SETTINGS:
		{
			if(text == "Game Properties")
			{
				new GameSettings();
			}
			else if(text == "Preferences")
			{
				new Preferences();
			}
			else if(text == "Disable Tool Tips")
			{
				Config::Get()->setEnableToolTips(false);
				
				gedString *pEnableDisableToolTips = listConfig->GetTextPtr("Disable Tool Tips");
				if(pEnableDisableToolTips)
				{
					*pEnableDisableToolTips = "Enable Tool Tips";
				}
			}
			else if(text == "Enable Tool Tips")
			{
				Config::Get()->setEnableToolTips(true);
				
				gedString *pEnableDisableToolTips = listConfig->GetTextPtr("Enable Tool Tips");
				if(pEnableDisableToolTips)
				{
					*pEnableDisableToolTips = "Disable Tool Tips";
				}
			}
		}
		break;
	case LS_REGIONS:
		{
			switch(index)
			{
			case 0: //Add Activation Region
#if !defined(GAME_EDITOR_HOME_EDITION)
				new RegionLoad();	
#else
				new PanelInfo(GAME_EDITOR_VERSION_ERROR);
				return true;
#endif
				break;
			case 1: //show/hide
				
				if(RegionLoad::getShowRegions())
				{
					*pShowHideRegions = "Show Regions";
				}
				else
				{
					*pShowHideRegions = "Hide Regions";
				}

				RegionLoad::ToggleVisibility();
				Actor::RegionActorToggleVisibility();
				break;
			}
		}
		break;
	case LS_HELP:
		{
			if(text == "Documentation")
			{
				EditorDirectory editDir;
				
				//Firefox don't open "Docs/index.html" in windows
				//So, use \ on windows and / on linux
			
				openUrl((
#if defined(__MACOSX__)
		gedString("file://")+	GameControl::Get()->getHomePath()+gedString("/")+		 
#endif
						 
						 gedString("Docs") + DIR_SEP + "index.html").c_str());
			}
			else if(text == "About...")
			{
				new AboutDlg();
			}
			else if(text == "User Forums...")
			{
				openUrl("http://game-editor.com/forum");
			}	
#if !defined(__MACOSX__)
			else if(text == "Get Newest Tutorials...")
			{
				TutorialUpdateDlg::Call();
			}
			else if(text == "Check for Updates...")
			{
				UpdateCheck();
			}
#endif // No check for updates outside MACOSX appstore due to apple guidelines
			else if(text == "Game Demos...")
			{
				openUrl("http://game-editor.com/demos.html");				
			}
			else
			{
				//Tutorials
				if(chdir((GameControl::getEditorPath() + DIR_SEP + "Tutorials" + DIR_SEP + text).c_str()) == 0)
				{				
					listTutorialDir->RemoveAll();
					listTutorialDir->getImage()->SetVisible(true);				
					PostMessage(this, 0);
				}
			}
		}
		break;
	case LS_TUTORIALDIR:
		{		
			PanelQuestion *panel = new PanelQuestion("This will discard the current game.\nProceed anyway?", "Tutorial Execution");
			if(panel->Wait() == OK_BUTTON)
			{
				PostMessage(this, 1);					
			}

			delete panel;	
			
		}
		break;

	case LS_EDIT_MENU:
		{
			switch(index)
			{
			case 0:
				editBoxWidget->Cut();
				break;

			case 1:
				editBoxWidget->Copy();
				break;

			case 2:
				editBoxWidget->Paste();
				break;
			}			
		}
		break;

	case LS_SCRIPT:
		{
			if(text == "Global code")
			{
				new ScriptGlobals();
			}
			else
			{
				stAction *action = (stAction *)list->GetItemData(index);
				gedString actorName(text.substr(0, text.find(' ')));

				Actor *actor = GameControl::Get()->GetActor(actorName);								

				if(actor && action)
				{
					AddLastScript(text);
					Action::ShowActionDialog(action, actor);			
				}
			}
		}
		break;
	}

	return true;
}
Example #3
0
void MainPanel::OnKeyDown(SDLKey key, int repeatLoopCount)
{
	if(GameControl::Get()->getStandAloneMode() || GameControl::Get()->getGameMode()) return;
	
	//Don't works in some systems if called in key up (don't works on Ingrid computer)
	//May be ctrl is up when other key is up
	SDLMod keyMod = SDL_GetModState();
	
	if((keyMod & KMOD_RCTRL) || (keyMod & KMOD_LCTRL))
	{
		switch(key)
		{
			
		case SDLK_z:
			if(PathDialog::getPathDialog())
			{
				new PanelInfo("Undo is not available while editing paths");
			}
			else if(!UndoControl::Get()->Undo())
			{
				new PanelInfo("No previous operation to undo");
			}
			break;
			
		case SDLK_y:
		case SDLK_r:
			if(PathDialog::getPathDialog())
			{
				new PanelInfo("Redo is not available while editing paths");
			}
			else if(!UndoControl::Get()->Redo())
			{
				new PanelInfo("No next operation to redo");
			}
			break;

		  case SDLK_s: // save/save as
		    if((keyMod & KMOD_LSHIFT) || (keyMod & KMOD_RSHIFT)) // save as
		    {
		      new LoadSaveGame(SAVE_GAME);
		    }
		    else // save
		    {
		      gedString gamePath(GameControl::Get()->getGamePath());
		      if(!gamePath.empty())
		      {
			LoadSaveGame::Save(gamePath + DIR_SEP + GameControl::Get()->getGameName());
		      }
		      else
		      {
			new LoadSaveGame(SAVE_GAME);
		      }
		    } 
		    break;

		  case SDLK_l: // load
		    new LoadSaveGame(LOAD_GAME);
		    break;

		  case SDLK_e: // export
		    new ExportGame();
		    break;

		  case SDLK_a: // create actor
		    new AddActor();
		    break;

		  case SDLK_g: // game mode
		    if(GenericScript::ParserAll())
		    {		       
		      UndoControl::Get()->PushCurrentState();
		      RegionLoad::UpdateRegions();
		      GameControl::Get()->StoreScreenSize();
		      GameControl::Get()->SetGameMode(true);
		    }
		    else
		    {
		      new PanelInfo(GenericScript::GetError(), "Error", ALIGN_LEFT);
		    }
		    break;

		  case SDLK_q: // quit
		    SDL_Event event;
		    memset(&event, 0, sizeof(SDL_Event));
		    event.quit.type = SDL_QUIT;
		    SDL_PushEvent(&event);
		    break;

		  case SDLK_p: // actor property
		  case SDLK_RETURN:
		    ActorProperty::Call(GameControl::Get()->GetActor("view"));
		    break;

		  case SDLK_o:
		    new ScriptGlobals();
		    break;

		    // nudge actor
		  case SDLK_LEFT: // nudge left
		  {
		    int offset = ((keyMod & KMOD_LSHIFT) || (keyMod & KMOD_RSHIFT)) ? 5 : 1;
		    Actor* eventActor = ActorProperty::getActorProperty()->GetCurrentEventActor();
		    eventActor->SetPos(eventActor->getX()-offset, eventActor->getY());
		  }
		  break;

		  case SDLK_RIGHT: // nudge right
		  {
		    int offset = ((keyMod & KMOD_LSHIFT) || (keyMod & KMOD_RSHIFT)) ? 5 : 1;
		    Actor* eventActor = ActorProperty::getActorProperty()->GetCurrentEventActor();
		    eventActor->SetPos(eventActor->getX()+offset, eventActor->getY());
		  }
		  break;

		  case SDLK_UP: // nudge up
		  {
		    int offset = ((keyMod & KMOD_LSHIFT) || (keyMod & KMOD_RSHIFT)) ? 5 : 1;
		    Actor* eventActor = ActorProperty::getActorProperty()->GetCurrentEventActor();
		    eventActor->SetPos(eventActor->getX(), eventActor->getY()-offset);
		  }
		  break;

		  case SDLK_DOWN: // nudge down
		  {
		    int offset = ((keyMod & KMOD_LSHIFT) || (keyMod & KMOD_RSHIFT)) ? 5 : 1;
		    Actor* eventActor = ActorProperty::getActorProperty()->GetCurrentEventActor();
		    eventActor->SetPos(eventActor->getX(), eventActor->getY()+offset);
		  }
		  break;

		  case SDLK_BACKSPACE:
		    Actor* eventActor = ActorProperty::getActorProperty()->GetCurrentEventActor();
			ActorProperty::getActorProperty()->RemoveActor(eventActor);
		    break;
		}
	}
	else
	{
	  switch(key)
	  {
	    case SDLK_l: // lock
	      Actor* eventActor = ActorProperty::getActorProperty()->GetCurrentEventActor();
	      eventActor->setLocked(!eventActor->IsLocked());
	      break;
	  }
	}

}
Example #4
0
void updateGamelist(SystemData* system)
{
	//We do this by reading the XML again, adding changes and then writing it back,
	//because there might be information missing in our systemdata which would then miss in the new XML.
	//We have the complete information for every game though, so we can simply remove a game
	//we already have in the system from the XML, and then add it back from its GameData information...

	if(Settings::getInstance()->getBool("IgnoreGamelist"))
		return;

	pugi::xml_document doc;
	pugi::xml_node root;
	std::string xmlReadPath = system->getGamelistPath(false);

	if(boost::filesystem::exists(xmlReadPath))
	{
		//parse an existing file first
		pugi::xml_parse_result result = doc.load_file(xmlReadPath.c_str());
		
		if(!result)
		{
			LOG(LogError) << "Error parsing XML file \"" << xmlReadPath << "\"!\n	" << result.description();
			return;
		}

		root = doc.child("gameList");
		if(!root)
		{
			LOG(LogError) << "Could not find <gameList> node in gamelist \"" << xmlReadPath << "\"!";
			return;
		}
	}else{
		//set up an empty gamelist to append to
		root = doc.append_child("gameList");
	}


	//now we have all the information from the XML. now iterate through all our games and add information from there
	FileData* rootFolder = system->getRootFolder();
	if (rootFolder != nullptr)
	{
		//get only files, no folders
		std::vector<FileData*> files = rootFolder->getFilesRecursive(GAME | FOLDER);
		//iterate through all files, checking if they're already in the XML
		std::vector<FileData*>::const_iterator fit = files.cbegin();
		while(fit != files.cend())
		{
			const char* tag = ((*fit)->getType() == GAME) ? "game" : "folder";

			// check if current file has metadata, if no, skip it as it wont be in the gamelist anyway.
			if ((*fit)->metadata.isDefault()) {
				++fit;
				continue;
			}

			// check if the file already exists in the XML
			// if it does, remove it before adding
			for(pugi::xml_node fileNode = root.child(tag); fileNode; fileNode = fileNode.next_sibling(tag))
			{
				pugi::xml_node pathNode = fileNode.child("path");
				if(!pathNode)
				{
					LOG(LogError) << "<" << tag << "> node contains no <path> child!";
					continue;
				}

				fs::path nodePath = resolvePath(pathNode.text().get(), system->getStartPath(), true);
				fs::path gamePath((*fit)->getPath());
				if(nodePath == gamePath || (fs::exists(nodePath) && fs::exists(gamePath) && fs::equivalent(nodePath, gamePath)))
				{
					// found it
					root.remove_child(fileNode);
					break;
				}
			}

			// it was either removed or never existed to begin with; either way, we can add it now
			addFileDataNode(root, *fit, tag, system);

			++fit;
		}

		//now write the file

		//make sure the folders leading up to this path exist (or the write will fail)
		boost::filesystem::path xmlWritePath(system->getGamelistPath(true));
		boost::filesystem::create_directories(xmlWritePath.parent_path());

		if (!doc.save_file(xmlWritePath.c_str())) {
			LOG(LogError) << "Error saving gamelist.xml to \"" << xmlWritePath << "\" (for system " << system->getName() << ")!";
		}
	}else{
		LOG(LogError) << "Found no root folder for system \"" << system->getName() << "\"!";
	}
}
Example #5
0
EditGameDialog::EditGameDialog(const String &domain, const String &desc)
	: OptionsDialog(domain, "GameOptions") {
	// Retrieve all game specific options.
	const EnginePlugin *plugin = 0;
	// To allow for game domains without a gameid.
	// TODO: Is it intentional that this is still supported?
	String gameId(ConfMan.get("gameid", domain));
	if (gameId.empty())
		gameId = domain;
	// Retrieve the plugin, since we need to access the engine's MetaEngine
	// implementation.
	EngineMan.findGame(gameId, &plugin);
	if (plugin) {
		_engineOptions = (*plugin)->getExtraGuiOptions(domain);
	} else {
		warning("Plugin for target \"%s\" not found! Game specific settings might be missing", domain.c_str());
	}

	// GAME: Path to game data (r/o), extra data (r/o), and save data (r/w)
	String gamePath(ConfMan.get("path", _domain));
	String extraPath(ConfMan.get("extrapath", _domain));
	String savePath(ConfMan.get("savepath", _domain));

	// GAME: Determine the description string
	String description(ConfMan.get("description", domain));
	if (description.empty() && !desc.empty()) {
		description = desc;
	}

	// GUI:  Add tab widget
	TabWidget *tab = new TabWidget(this, "GameOptions.TabWidget");

	//
	// 1) The game tab
	//
	tab->addTab(_("Game"));

	// GUI:  Label & edit widget for the game ID
	if (g_system->getOverlayWidth() > 320)
		new StaticTextWidget(tab, "GameOptions_Game.Id", _("ID:"), _("Short game identifier used for referring to saved games and running the game from the command line"));
	else
		new StaticTextWidget(tab, "GameOptions_Game.Id", _c("ID:", "lowres"), _("Short game identifier used for referring to saved games and running the game from the command line"));
	_domainWidget = new DomainEditTextWidget(tab, "GameOptions_Game.Domain", _domain, _("Short game identifier used for referring to saved games and running the game from the command line"));

	// GUI:  Label & edit widget for the description
	if (g_system->getOverlayWidth() > 320)
		new StaticTextWidget(tab, "GameOptions_Game.Name", _("Name:"), _("Full title of the game"));
	else
		new StaticTextWidget(tab, "GameOptions_Game.Name", _c("Name:", "lowres"), _("Full title of the game"));
	_descriptionWidget = new EditTextWidget(tab, "GameOptions_Game.Desc", description, _("Full title of the game"));

	// Language popup
	_langPopUpDesc = new StaticTextWidget(tab, "GameOptions_Game.LangPopupDesc", _("Language:"), _("Language of the game. This will not turn your Spanish game version into English"));
	_langPopUp = new PopUpWidget(tab, "GameOptions_Game.LangPopup", _("Language of the game. This will not turn your Spanish game version into English"));
	_langPopUp->appendEntry(_("<default>"), (uint32)Common::UNK_LANG);
	_langPopUp->appendEntry("", (uint32)Common::UNK_LANG);
	const Common::LanguageDescription *l = Common::g_languages;
	for (; l->code; ++l) {
		if (checkGameGUIOptionLanguage(l->id, _guioptionsString))
			_langPopUp->appendEntry(l->description, l->id);
	}

	// Platform popup
	if (g_system->getOverlayWidth() > 320)
		_platformPopUpDesc = new StaticTextWidget(tab, "GameOptions_Game.PlatformPopupDesc", _("Platform:"), _("Platform the game was originally designed for"));
	else
		_platformPopUpDesc = new StaticTextWidget(tab, "GameOptions_Game.PlatformPopupDesc", _c("Platform:", "lowres"), _("Platform the game was originally designed for"));
	_platformPopUp = new PopUpWidget(tab, "GameOptions_Game.PlatformPopup", _("Platform the game was originally designed for"));
	_platformPopUp->appendEntry(_("<default>"));
	_platformPopUp->appendEntry("");
	const Common::PlatformDescription *p = Common::g_platforms;
	for (; p->code; ++p) {
		_platformPopUp->appendEntry(p->description, p->id);
	}

	//
	// 2) The engine tab (shown only if there are custom engine options)
	//
	if (_engineOptions.size() > 0) {
		tab->addTab(_("Engine"));

		addEngineControls(tab, "GameOptions_Engine.", _engineOptions);
	}

	//
	// 3) The graphics tab
	//
	_graphicsTabId = tab->addTab(g_system->getOverlayWidth() > 320 ? _("Graphics") : _("GFX"));

	if (g_system->getOverlayWidth() > 320)
		_globalGraphicsOverride = new CheckboxWidget(tab, "GameOptions_Graphics.EnableTabCheckbox", _("Override global graphic settings"), 0, kCmdGlobalGraphicsOverride);
	else
		_globalGraphicsOverride = new CheckboxWidget(tab, "GameOptions_Graphics.EnableTabCheckbox", _c("Override global graphic settings", "lowres"), 0, kCmdGlobalGraphicsOverride);

	addGraphicControls(tab, "GameOptions_Graphics.");

	//
	// 4) The audio tab
	//
	tab->addTab(_("Audio"));

	if (g_system->getOverlayWidth() > 320)
		_globalAudioOverride = new CheckboxWidget(tab, "GameOptions_Audio.EnableTabCheckbox", _("Override global audio settings"), 0, kCmdGlobalAudioOverride);
	else
		_globalAudioOverride = new CheckboxWidget(tab, "GameOptions_Audio.EnableTabCheckbox", _c("Override global audio settings", "lowres"), 0, kCmdGlobalAudioOverride);

	addAudioControls(tab, "GameOptions_Audio.");
	addSubtitleControls(tab, "GameOptions_Audio.");

	//
	// 5) The volume tab
	//
	if (g_system->getOverlayWidth() > 320)
		tab->addTab(_("Volume"));
	else
		tab->addTab(_c("Volume", "lowres"));

	if (g_system->getOverlayWidth() > 320)
		_globalVolumeOverride = new CheckboxWidget(tab, "GameOptions_Volume.EnableTabCheckbox", _("Override global volume settings"), 0, kCmdGlobalVolumeOverride);
	else
		_globalVolumeOverride = new CheckboxWidget(tab, "GameOptions_Volume.EnableTabCheckbox", _c("Override global volume settings", "lowres"), 0, kCmdGlobalVolumeOverride);

	addVolumeControls(tab, "GameOptions_Volume.");

	//
	// 6) The MIDI tab
	//
	_globalMIDIOverride = NULL;
	if (!_guioptions.contains(GUIO_NOMIDI)) {
		tab->addTab(_("MIDI"));

		if (g_system->getOverlayWidth() > 320)
			_globalMIDIOverride = new CheckboxWidget(tab, "GameOptions_MIDI.EnableTabCheckbox", _("Override global MIDI settings"), 0, kCmdGlobalMIDIOverride);
		else
			_globalMIDIOverride = new CheckboxWidget(tab, "GameOptions_MIDI.EnableTabCheckbox", _c("Override global MIDI settings", "lowres"), 0, kCmdGlobalMIDIOverride);

		addMIDIControls(tab, "GameOptions_MIDI.");
	}

	//
	// 7) The MT-32 tab
	//
	_globalMT32Override = NULL;
	if (!_guioptions.contains(GUIO_NOMIDI)) {
		tab->addTab(_("MT-32"));

		if (g_system->getOverlayWidth() > 320)
			_globalMT32Override = new CheckboxWidget(tab, "GameOptions_MT32.EnableTabCheckbox", _("Override global MT-32 settings"), 0, kCmdGlobalMT32Override);
		else
			_globalMT32Override = new CheckboxWidget(tab, "GameOptions_MT32.EnableTabCheckbox", _c("Override global MT-32 settings", "lowres"), 0, kCmdGlobalMT32Override);

		addMT32Controls(tab, "GameOptions_MT32.");
	}

	//
	// 8) The Paths tab
	//
	if (g_system->getOverlayWidth() > 320)
		tab->addTab(_("Paths"));
	else
		tab->addTab(_c("Paths", "lowres"));

	// These buttons have to be extra wide, or the text will be truncated
	// in the small version of the GUI.

	// GUI:  Button + Label for the game path
	if (g_system->getOverlayWidth() > 320)
		new ButtonWidget(tab, "GameOptions_Paths.Gamepath", _("Game Path:"), 0, kCmdGameBrowser);
	else
		new ButtonWidget(tab, "GameOptions_Paths.Gamepath", _c("Game Path:", "lowres"), 0, kCmdGameBrowser);
	_gamePathWidget = new StaticTextWidget(tab, "GameOptions_Paths.GamepathText", gamePath);

	// GUI:  Button + Label for the additional path
	if (g_system->getOverlayWidth() > 320)
		new ButtonWidget(tab, "GameOptions_Paths.Extrapath", _("Extra Path:"), _("Specifies path to additional data used by the game"), kCmdExtraBrowser);
	else
		new ButtonWidget(tab, "GameOptions_Paths.Extrapath", _c("Extra Path:", "lowres"), _("Specifies path to additional data used by the game"), kCmdExtraBrowser);
	_extraPathWidget = new StaticTextWidget(tab, "GameOptions_Paths.ExtrapathText", extraPath, _("Specifies path to additional data used by the game"));

	_extraPathClearButton = addClearButton(tab, "GameOptions_Paths.ExtraPathClearButton", kCmdExtraPathClear);

	// GUI:  Button + Label for the save path
	if (g_system->getOverlayWidth() > 320)
		new ButtonWidget(tab, "GameOptions_Paths.Savepath", _("Save Path:"), _("Specifies where your saved games are put"), kCmdSaveBrowser);
	else
		new ButtonWidget(tab, "GameOptions_Paths.Savepath", _c("Save Path:", "lowres"), _("Specifies where your saved games are put"), kCmdSaveBrowser);
	_savePathWidget = new StaticTextWidget(tab, "GameOptions_Paths.SavepathText", savePath, _("Specifies where your saved games are put"));

	_savePathClearButton = addClearButton(tab, "GameOptions_Paths.SavePathClearButton", kCmdSavePathClear);

	// Activate the first tab
	tab->setActiveTab(0);
	_tabWidget = tab;

	// Add OK & Cancel buttons
	new ButtonWidget(this, "GameOptions.Cancel", _("Cancel"), 0, kCloseCmd);
	new ButtonWidget(this, "GameOptions.Ok", _("OK"), 0, kOKCmd);
}